几个被淘汰的Python库,请不要再用!

随着每个 Python/ target=_blank class=infotextkey>Python 版本的发布,都会添加新模块,并引入新的更好的做事方式,虽然我们都习惯了使用好的旧 Python 库和某些做事方式,但现在也时候升级并利用新的和改进的模块及其特性了 。

几个被淘汰的Python库,请不要再用!

文章插图
Pathlib 而不是 OSpathlib 绝对是 Python 标准库中最近添加的更大的内容之一,自 Python 3.4 以来,它一直是标准库的一部分,但很多人仍然使用 os 模块进行文件系统操作 。
然而,pathlib 与旧的 os.path 相比具有许多优点 - 虽然 os 模块以原始字符串格式表示路径,但 pathlib 使用面向对象的样式,这使得它更具可读性和编写自然:
from pathlib import Pathimport os.path# 老方式two_dirs_up = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 新方式,可读性强two_dirs_up = Path(__file__).resolve().parent.parent路径被视为对象而不是字符串这一事实也使得可以创建一次对象,然后查找其属性或对其进行操作:
readme = Path("README.md").resolve()print(f"Absolute path: {readme.absolute()}")# Absolute path: /home/martin/some/path/README.mdprint(f"File name: {readme.name}")# File name: README.mdprint(f"Path root: {readme.root}")# Path root: /print(f"Parent directory: {readme.parent}")# Parent directory: /home/martin/some/pathprint(f"File extension: {readme.suffix}")# File extension: .mdprint(f"Is it absolute: {readme.is_absolute()}")# Is it absolute: True我最喜欢 pathlib 的一个特性是可以使用 /(“除法”)运算符来连接路径:
# Operators:etc = Path('/etc')joined = etc / "cron.d" / "anacron"print(f"Exists? - {joined.exists()}")# Exists? - True重要的是要注意 pathlib 只是替代 os.path 而不是整个 os 模块,它还包括 glob 模块的功能,因此如果你习惯于将 os.path 与 glob.glob 结合使用,那么你可以完全用pathlib替代它们 。
在上面的片段中,我们展示了一些方便的路径操作和对象属性,但 pathlib 还包括你习惯于 os.path 的所有方法,例如:
print(f"Working directory: {Path.cwd()}")# same as os.getcwd()# Working directory: /home/martin/some/pathPath.mkdir(Path.cwd() / "new_dir", exist_ok=True)# same as os.makedirs()print(Path("README.md").resolve())# same as os.path.abspath()# /home/martin/some/path/README.mdprint(Path.home())# same as os.path.expanduser()# /home/martin有关 os.path 函数到 pathlib 中新函数的完整映射,请参阅 官方文档 。
Secrets 而不是 OS说到 os 模块,你应该停止使用的另一部分是 os.urandom 。相反,你应该使用自 Python 3.6 以来可用的新秘密模块:
# 老方式:import oslength = 64value = https://www.isolves.com/it/cxkf/yy/Python/2023-06-29/os.urandom(length)print(f"Bytes: {value}")# Bytes: b'xfaxf3...xf2x1bxf5xb6'print(f"Hex: {value.hex()}")# Hex: faf3cc656370e31a938e7...33d9b023c3c24f1bf5# 新方式:import secretsvalue = secrets.token_bytes(length)print(f"Bytes: {value}")# Bytes: b'Uxe9nx87...x85>x04j:xb0'value = secrets.token_hex(length)print(f"Hex: {value}")# Hex: fb5dd85e7d73f7a08b8e3...4fd9f95beb08d77391使用 os.urandom 实际上并不是这里的问题,引入secrets模块的原因是因为人们使用随机模块来生成密码等,即使随机模块不产生密码安全令牌 。
根据文档,随机模块不应用于安全目的,你应该使用 secrets 或 os.urandom,但 secrets 模块绝对更可取,因为它比较新,并且包含一些用于十六进制令牌的实用程序/便利方法以及 URL 安全令牌 。
Zoneinfo 而不是 pytz在 Python 3.9 之前,没有用于时区操作的内置库,所以每个人都在使用 pytz,但现在我们在标准库中有 zoneinfo,所以是时候切换了 。
from datetime import datetimeimport pytz# pip install pytzdt = datetime(2022, 6, 4)nyc = pytz.timezone("America/New_York")localized = nyc.localize(dt)print(f"Datetime: {localized}, Timezone: {localized.tzname()}, TZ Info: {localized.tzinfo}")# 新方式:from zoneinfo import ZoneInfonyc = ZoneInfo("America/New_York")localized = datetime(2022, 6, 4, tzinfo=nyc)print(f"Datetime: {localized}, Timezone: {localized.tzname()}, TZ Info: {localized.tzinfo}")# Datetime: 2022-06-04 00:00:00-04:00, Timezone: EDT, TZ Info: America/New_Yorkdatetime 模块将所有时区操作委托给抽象基类 datetime.tzinfo,这个抽象基类需要一个具体的实现——在引入这个很可能来自 pytz 的模块之前 。现在我们在标准库中有 zoneinfo,我们可以使用它 。
然而,使用 zoneinfo 有一个警告——它假定系统上有可用的时区数据,UNIX 系统就是这种情况,如果你的系统没有时区数据,那么你应该使用 tzdata 包,它是由 CPython 核心开发人员维护的第一方库,其中包含 IANA 时区数据库 。


推荐阅读