译: 《Summary of Major Changes Between Python Versions》 https://www.nicholashairs.com/posts/major-changes-between-python-versions/
在这里插入图片描述
本文总结了Python 3.7到3.12的语法及标准库的主要更改,并且介绍了typing
模块的主要更改。此外,还提到了各个版本的EOL
(End of Life,Python官方不再提供安全补丁的日期)。
python3.7版本在2023年7月
EOL。
3.5+:
async
和await
a @ b
3.6+:
1_000_000
(3.6+)3.7+:
walrus
操作符) :=
if (thing := get_thing()) is not None:
do_something(thing)
else:
raise Exception(f"Something is wrong with {thing}")
positional-only parameters
)def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
# Before
f"user={user}"
# Now
f"{user=}"
import importlib.metadata
importlib.metadata.version("some-library")
# "2.3.4"
importlib.metadata.requires("some-library")
# ["thing==1.2.4", "other>=5"]
importlib.metadata.files("some-library")
# [...]
TypedDict
, Literal
, Final
, Protocol
dict[...]
, list[...]
, set[...]
替代之前的 typing.Dict
, List
, Set
removeprefix
和removesuffix
更安全地从开头或结尾删除内容。这比字符串切片更安全。if header.startswith("X-Forwarded-"):
section = header.removeprefix("X-Forwarded-")
|
(PEP 584)combined_dict = dict_one | dict_two
updated_dict |= dict_three
my_int: Annotated[int, SomeRange(0, 255)] = 0
import zoneinfo
some_zone = zoneinfo.ZoneInfo("Europe/Berlin")
match command.split():
case ["quit"]:
print("Goodbye!")
quit_game()
case ["look"]:
current_room.describe()
case ["get", obj]:
character.get(obj, current_room)
case "go", direction:
current_room = current_room.neighbor(direction)
case [action]:
.. # interpret single-verb action
case [action, obj]:
... # interpret action, obj
case _:
... # anything that didn't match
|
表示并# Before
from typing import Optional, Union
thing: Optional[Union[str, list[str]]] = None
# Now
thing: str | list[str] | None = None
Callable
(及类似类型)时更好地传递键入信息。
from typing import Awaitable, Callable, ParamSpec, TypeVar
P = ParamSpec("P")
R = TypeVar("R")
def add_logging(f: Callable[P, R]) -> Callable[P, Awaitable[R]]:
async def inner(*args: P.args, **kwargs: P.kwargs) -> R:
await log_to_database()
return f(*args, **kwargs)
return inner
@add_logging
def takes_int_str(x: int, y: str) -> int:
return x + 7
await takes_int_str(1, "A") # Accepted
await takes_int_str("B", 2) # Correctly rejected by the type checker
TypeAlias
(PEP 613)StrCache: TypeAlias = 'Cache[str]' # a type alias
LOG_PREFIX = 'LOG[DEBUG]' # a module constant
TypeGuard
(PEP 647)
_T = TypeVar("_T")
def is_two_element_tuple(val: Tuple[_T, ...]) -> TypeGuard[Tuple[_T, _T]]:
return len(val) == 2
def func(names: Tuple[str, ...]):
if is_two_element_tuple(names):
reveal_type(names) # Tuple[str, str]
else:
reveal_type(names) # Tuple[str, ...]
with (CtxManager() as example):
...
with (
CtxManager1(),
CtxManager2()
):
...
with (CtxManager1() as example, CtxManager2()):
...
with (CtxManager1(), CtxManager2() as example):
...
with (
CtxManager1() as example1,
CtxManager2() as example2,
):
...
slots
, kw_only
数据类装饰器现在支持以下功能:
kw_only=True
: __init__
的所有参数都将标记为仅关键字
slots=True
:生成的数据类将用__slots__
存储数据ExceptionGroup
和 BaseExceptionGroup
使得对异常进行分组并将它们一起引发成为可能,并且新的 except*
语法泛化了 except
,以匹配异常组的子组。add_note()
方法。它可以用于为异常添加上下文信息,这些信息在引发异常时不可用。添加的注释将出现在默认的回溯信息中。try:
do_something()
except BaseException as e:
e.add_note("this happened during do_something")
raise
class MyClass:
@classmethod
def from_hex(cls, s: str) -> Self: # Self means instance of cls
return cls(int(s, 16))
def frobble(self, x: int) -> Self: # Self means this instance
self.y >> x
return self
LiteralString
注解用于指示函数参数可以是任何字面字符串类型。这允许函数接受任意字面字符串类型,以及从其他字面字符串创建的字符串。类型检查器可以强制执行只能使用静态参数调用敏感函数(例如执行SQL语句或shell命令的函数),从而提供对注入攻击的保护。# default is required
class Movie(TypedDict):
title: str
year: NotRequired[int]
# default is not-required
class Movie(TypedDict, total=False):
title: Required[str]
year: int
TypeVar
,可以创建以单个类型参数化的泛型。PEP 646添加了TypeVarTuple
,可以使用任意数量的类型进行参数化。换句话说,TypeVarTuple
是一个可变参数类型变量,可以实现可变参数泛型。
这支持各种用例。特别是,它允许使用 NumPy 和 TensorFlow 等数值计算库中的类似数组结构的类型进行参数化。静态类型检查器现在将能够捕获使用这些库的代码中与形状相关的错误。dataclass_transform
可以用来装饰类、元类或者本身就是装饰器的函数。使用@dataclass_transform()
告诉静态类型检查器,被装饰的对象执行了运行时的“魔法”,可以将一个类转换为具有类似dataclass
行为的形式。
# The create_model decorator is defined by a library.
@typing.dataclass_transform()
def create_model(cls: Type[T]) -> Type[T]:
cls.__init__ = ...
cls.__eq__ = ...
cls.__ne__ = ...
return cls
# The create_model decorator can now be used to create new model classes:
@create_model
class CustomerModel:
id: int
name: str
*
解包for x in *a, *b:
print(x)
def max[T](args: Iterable[T]) -> T:
...
class list[T]:
def __getitem__(self, index: int, /) -> T:
...
def append(self, element: T) -> None:
...
能够使用 type
语句声明类型别名(generate TypeAliasType)
type Point = tuple[float, float]
# Type aliases can also be generic
type Point[T] = tuple[T, T]
## Can re-use quotes
f"This is the playlist: {", ".join(songs)}"
f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" # '2'
## Multiline f-string with comments
f"This is the playlist: {", ".join([
'Take me back to Eden', # My, my, those eyes like fire
'Alkaline', # Not acid nor alkaline
'Ascensionism' # Take to the broken skies at last
])}"
## Backslashes / Unicode
f"This is the playlist: {"\n".join(songs)}"
f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}"
__buffer__()
方法的类现在可用作buffer类型。 新的 collections.abc.Buffer
ABC 提供了一种表示缓冲区对象的标准方法。例如在类型注释中,inspect.BufferFlags
枚举表示可用于自定义缓冲区创建的标志。from typing import TypedDict, Unpack
class Movie(TypedDict):
name: str
year: int
def foo(**kwargs: Unpack[Movie]):
...
from typing import override
class Base:
def get_color(self) -> str:
return "blue"
class GoodChild(Base):
@override # ok: overrides Base.get_color
def get_color(self) -> str:
return "yellow"
class BadChild(Base):
@override # type checker error: does not override Base.get_color
def get_colour(self) -> str:
return "red"
from __future__ import annotations
这允许解释器使用这种新格式进行解析。
注意:PEP 563 将被 PEP 649 取代,PEP 649 将在 Python 3.13 中实现。
typing_extensions
库向后移植typing功能,以便它们可用于检查旧代码库的类型检查器。
import sys
if sys.version_info < (3, 10):
from typing_extensions import TypeAlias
else:
from typing import TypeAlias
https://endoflife.date/python
https://github.com/astral-sh/ruff
Ruff
是一个用 Rust 编写的 linter 和代码格式化程序。它变得非常流行,因为它的速度非常快。它还包括自动修复错误的能力。
可以将 ruff
与它的pyupgrade兼容 linter(UP
)结合使用,通过ruff check --fix
自动升级代码库。
使用pyproject.toml
时,ruff将遵循project.requires-python
。
此工具可用于自动升级代码库。
https://github.com/asottile/pyupgrade
black是一个流行的代码格式化程序。
使用pyproject.toml
时,black将遵循project.requires-python
。