Python 10 新特性

Python 10

  • PEP 623 -- Deprecate and prepare for the removal of the wstr member in PyUnicodeObject.
  • PEP 604 -- Allow writing union types as X | Y
  • PEP 612 -- Parameter Specification Variables
  • PEP 626 -- Precise line numbers for debugging and other tools.
  • PEP 618 -- Add Optional Length-Checking To zip.
  • bpo-12782: Parenthesized context managers are now officially allowed.
  • PEP 632 -- Deprecate distutils module.
  • PEP 613 -- Explicit Type Aliases
  • PEP 634 -- Structural Pattern Matching: Specification
  • PEP 635 -- Structural Pattern Matching: Motivation and Rationale
  • PEP 636 -- Structural Pattern Matching: Tutorial
  • PEP 644 -- Require OpenSSL 1.1.1 or newer
  • PEP 624 -- Remove Py_UNICODE encoder APIs
  • PEP 597 -- Add optional EncodingWarning

PEP 623 624

623: 弃用并准备删除 PyUnicodeObject 中的 wstr 成员。 624: 删除 Py_UNICODE 编码器 API

与C相关, 略

PEP 604

允许将Union类型写为 X | Y

在Python10之前, 标识数据类型, 用于类型检查时, 是这样的.

from typing import Union


def fun9(var: Union[None, int, str]) -> str:
    """var 可以是 None, 或者 int 类型, 或者 str 类型"""
    if var is None:
        return 'null'
    if isinstance(var, int):
        return str(var)
    return var
复制代码

现在在Python10中, 可以这样写.

def fun10(var: None | int | str) -> str:
    if var is None:
        return 'null'
    if isinstance(var, int):
        return str(var)
    return var
复制代码

PEP 612

参数规范变量

ParamSpec

简单来说就是, 装饰器装饰不同函数, 无法明确指定参数类型, 但是又希望能进行代码(参数类型)检查, 有点像其他语言(Java)泛型的意思. 在Python10之前是不能进行代码检查的, 例如

在Python10之前, Callable 类型的参数类型检查无法传递

from typing import Awaitable, Callable, TypeVar

R = TypeVar("R")


def add_logging(f: Callable[..., R]) -> Callable[..., Awaitable[R]]:
    """...表示忽略检查, 就是什么都可以"""
    def inner(*args: object, **kwargs: object) -> R:
        return f(*args, **kwargs)

    return inner


@add_logging
def takes_int_str(x: int, y: str) -> int:
    return x + 7


takes_int_str(1, "A")
takes_int_str("B", 2)  # 代码检查器未检测出问题, 但实际确是错的, 运行时将出错

复制代码

在Python10中, 现在可以这样

目前这个代码在 PyCharm 会报错, 可能还没跟进此特性吧, 但运行是没有问题的.

pylint貌似现在也检测不出来这个问题.

扫描二维码关注公众号,回复: 13168618 查看本文章
from typing import Awaitable, Callable, TypeVar, ParamSpec

P = ParamSpec("P")

R = TypeVar("R")


def add_logging(f: Callable[P, R]) -> Callable[P, Awaitable[R]]:
    """...表示忽略检查, 就是什么都可以"""

    def inner(*args: object, **kwargs: object) -> R:
        return f(*args, **kwargs)

    return inner


@add_logging
def takes_int_str(x: int, y: str) -> int:
    return x + 7


takes_int_str(1, "A")
takes_int_str("B", 2)  # 代码检查器将可以检测出问题, 符合预期

复制代码

Concatenate

在上面问题的基础上, 如果装饰器需要对函数参数进行扩展, 那代码检查器也是无法检测出来的, 甚至可能会报错, Python10之前无法处理这个问题, 但Python10在 typing 中添加 Concatenate 类型, 用于适应这种情况, 简单代码示例如下, 详情访问PEP 612

from typing import Concatenate

def with_request(f: Callable[Concatenate[Request, P], R]) -> Callable[P, R]:
  def inner(*args: P.args, **kwargs: P.kwargs) -> R:
    return f(Request(), *args, **kwargs)
  return inner

@with_request
def takes_int_str(request: Request, x: int, y: str) -> int:
  # use request
  return x + 7

takes_int_str(1, "A") # Accepted
takes_int_str("B", 2) # Correctly rejected by the type checker
复制代码

PEP 626

用于调试和其他工具的精确行号。

这个好像没什么好说的, 调试信息的精确行号.

PEP 618

添加可选的长度检查到 zip。

Python10 现在为 zip 函数, 添加了一个 strict 的关键字参数, 用于强制检查, 可遍历对象的长度一致, 提议者称, 如果不检查可遍历对象的长度一致, 可能会引发难以发现的错误.

# Python10之前的版本, 会报错, 原因是无 strict 关键字参数
# Python10版本也会报错, 因为启用了严格模式, 但是参数中的可迭代对象长度不相同

for a,b in zip([1,2,3],['a','b'], strict=True):
    print(a, b)
复制代码

bop 12782

现在正式允许带括号的上下文管理器。

简单来说是, 使用with打开多个文件时, 一行代码太长, 换行需要使用反斜杠, 但是现在不用了, 可以使用括号.

# 尽管直到 Python 3.10 才被“引入”,但由于新的 PEG 解析器,
# CPython 接受了新的语法更改——所以我们有了一个新特性,它与 3.9 完全兼容
# 引自: https://towardsdatascience.com/whats-new-in-python-3-10-a757c6c69342
with (open('src.txt') as src,
        open('dest.txt', 'w') as dest):
    dest.write(src.read())
复制代码

PEP 634 635 636

634: 结构模式匹配:规范 635: 结构模式匹配:动机和基本原理 636: 结构模式匹配:教程

在Python10中新加入了模式匹配的功能, 相当于其他语言的 switch...case 结构

def fun10(var: None | int | str) -> str:
    match type(var).__name__:
        case 'NoneType':
            return 'null'
        case 'int':
            return str(var)
        case _:
            return var
# 更多用法请参考 PEP 636
复制代码

PEP 644

需要 OpenSSL 1.1.1 或更新版本

PEP 597

添加可选的 EncodingWarning

猜你喜欢

转载自juejin.im/post/7019562595732422687