• PEP最新提案推出,Python将上线重大更新,带来了哪些新功能?


    Python在上线任何新功能之前,都需要由PEP,即Python增强提案(Python Enhancement Proposal)概述新功能内容。因此,了解PEP能够知道Python在未来可能会进行哪些更新。在本文中,我们将详细讨论即将推出的几项Python新功能的提案。我们将所有提案分为以下几类,分别是语法更改、类型标注、调试、生活质量、生态改善等。

    语法变化

    第一个提案是PEP 671,它提出了后期绑定参数默认值的语法。尽管Python中的函数可以将其他函数作为参数。但是,目前无法很好的为此类参数设置默认值。通常空值或哨兵值(全局常量)用作默认值,但这样help(function)无法在参数上使用。因此PEP 671中描述了使用=>( param=>func()) 将函数指定为默认参数的新语法。

     # Current solution:
    _SENTINEL = object()
    def func(param=_SENTINEL):
        if param is _SENTINEL:
            # default_param holds expected default value
            param = default_param
    # New solution:
    def func(param=>default_param):
        ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这种变化的确有效,但我们应该谨慎添加新的语法符号或是做出过多的语法更改。我们无法确定像这样的细微改进是否需要用到另一个赋值运算符。

    另一个语法更改相关的提案是PEP 654,它提出将except*作为用于引发异常组的新语法。这样做的基本原理是Python解释器一次只能传播一个异常,但有时需要在栈展开时传播多个不相关的异常。这样可能会导致asyncio带来并发错误或在执行重试逻辑时引发的多个不同异常,例如在连接到某个远程主机时出现异常。

    try:
        some_file_operation()
    except* OSError as eg:
        for e in eg.exceptions:
            print(type(e).__name__)
    # FileNotFoundError
    # FileExistsError
    # IsADirectoryError
    # PermissionError
    # ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    类型标注

    之后是PEP 673提案。这个提案不涉及typing模块相关知识。举个例子:假设你有一个带有set_name方法的Person类,能够返回self,即实例Person类。若在之后使用相同的set_name 创建子类Employee,它会返回类型实例Employee而不是Person类。这对如今的类型检查并不适用——在 Python 3.10 中,类型检查器将子类中的返回类型认定基类的返回类型。PEP 673能帮助类型检查器正确推断类型:

    class Person:
        def set_name(self, name: str) -> Self:
            self.name = name
            return self
    
    • 1
    • 2
    • 3
    • 4

    该PEP将作为Python 3.11版本的新功能推出。

    除此之外,PEP提出了另一个类型变化,即任意文字字符串。目前我们无法指定函数参数的类型可以是任意文字字符串(只能使用特定的文字字符串,例如Literal["foo"])。许多人觉得这不是什么大问题,甚至会疑惑为什么有人需要指定该参数应该是string,而不是(f-string)或是其他内插字符串。事实上,这主要涉及到一个安全问题——参数是literal的话能够避免受到注入攻击,无论是SQL/命令注入还是XSS等。拥有这一功能能使sqlite等库在不应该使用字符串插值的时候提醒用户,因此它的确有它的用处。

    调试

    PEP 669提出对CPython进行监控。此提案中提到应使用CPython进行低成本监控,这在运行调试器或分析器时不会影响Python的性能。考虑到在进行基本调试时并不会有性能损失,这对Python的用户影响不大。

    但这个功能在某些情况下非常有用,例如:

    • 调试只能在生产环境中重现而不影响应用程序性能的问题;
    • 调试会受到时间影响的竞争条件;
    • 在运行基准测试时进行调试。

    对于那些想要提高Python性能的人来说,这一功能非常有用,能促进调试和基准性能问题/改进的进度。

    同时,PEP 678中提到属性__note__应该添加到BaseException类中。此属性可用于保存可以作为回溯的一部分显示的附加调试信息。

    try:
        raise TypeError('Some error')
    except Exception as e:
        e.__note__ = 'Extra information'
        raise
    # Traceback (most recent call last):
    #   File "<stdin>", line 2, in <module>
    # TypeError: Some error
    # Extra information
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如上例所示,这能够在重新引发异常时起到作用。正如PEP 669中所提到的,这对于具有重试逻辑的库同样很有用,能够为每次的失败添加额外信息。同样,测试库可以为调试错误添加更多内容,例如变量名称和值。

    除了PEP 669,另一个与调试相关的是PEP 657,该提案中提到要为Python的每个字节码指令添加额外数据。这一数据能够生成更好的回溯信息。同时该提案还建议公开API,允许其他工具(例如分析器或静态分析工具)使用数据。

    这一提案看似普通,但实际上是所有提案中最实用的,因为能够带来更好的回溯信息,可以极大的改进回溯的可读性以及调试体验。

    生态系统

    PEP 680中建议Python的标准库支持解析TOML格式,而这可能会带来bootstrapping问题。除此之外,包括flake8在内的流行工具也不支持TOML,因为在标准库中缺乏支持。因此PEP 680建议将TOML支持添加到标准库中。

    在标准库中支持常见的格式是可行的,特别是那些对于Python工具和生态系统非常重要的格式。那么我们什么时候才能在标准库中支持YAML呢?

    最后一个提案是PEP 661,与“哨兵价值”有关。在Python中不能创建这类价值。如前面提到的PEP 671所示,哨兵价值通常需要用到_something = object,而PEP 661为标准库提出了标记值的具体规范:

    # Old:
    _sentinel = object()
    # New:
    from sentinels import sentinel
    some_name = sentinel("some_name")
    
    • 1
    • 2
    • 3
    • 4
    • 5

    以上就是Python即将上线的部分功能,未来还将会有哪些功能呢?让我们一起拭目以待吧!

    【参考资料】
    https://martinheinz.dev/blog/67

  • 相关阅读:
    JDK1.8新特性---Optional
    git 基础使用(上传,修改上传)
    基于Android的学生管理系统App设计与实现(Eclipse开发)
    中国大学科技园联盟携优积科技走进晋江 探索校地双向赋能新路径
    IO学习系列之获取系统的实时日期
    ubuntu虚拟环境安装以及远程jupyter
    Ubuntu18.04系统安装nginx
    46. 全排列
    泛微E9,独立选择框对应数据库表查询
    pip 安装dgl的问题
  • 原文地址:https://blog.csdn.net/weixin_39787030/article/details/122958816