前言

最近补一下各个 Python 新版本带来的那些对开发者有帮助的新特性。今天先说 Python3.9,这个版本很中庸,有价值的修改不多,就只放在一篇文章里列出啦。

字典增加合并运算符

PEP 584 – Add Union Operators To dict 里面提出给 dict 增加合并 (|) 与更新 (|=) 这 2 个运算符

过去合并 (Merge) 2 个字典有两种常见方法:

In : a = {'a': 1}

In : b = {'b': 1}

In : {**a, **b}  # 方案一,使用**,Python3.5及以上版本
Out: {'a': 1, 'b': 1}

In : c = a.copy() # 方案2,使用update

In : c.update(b)  # 如果直接使用a.update,会直接修改a的结果

当然除此之外还有一些比较 trick 的,尤其是 Python 2 阶段的dict(list(x.items()) + list(y.items()))这种就不提了。

Python 3.9 开始可以使用按位或运算符实现:

In : a = {'a': 1}

In : b = {'b': 1}

In : a | b
Out: {'a': 1, 'b': 1}

如果希望合并后直接替换,可以使用更新 (|=) 运算符:

In : a
Out: {'a': 1}

In : a |= b  # 相当于a.update(b)

In : a
Out: {'a': 1, 'b': 1}  # 在a上直接替换了(in place)

新增用于移除前缀和后缀的字符串方法

PEP 616 – String methods to remove prefixes and suffixes 里新增了removeprefixremovesuffix2 个字符串方法。而在过去需要自己实现:

def removeprefix(self: str, prefix: str, /) -> str:
    if self.startswith(prefix):
        return self[len(prefix):]
    else:
        return self[:]

def removesuffix(self: str, suffix: str, /) -> str:
    if suffix and self.endswith(suffix):
        return self[:-len(suffix)]
    else:
        return self[:]

当然,同时也增加了bytes, bytearray以及collections.UserString的对应方法。

我对这个功能的理解是可以基于它对 CPython 里面的代码做一些改进。

装饰器语法改进

在之前的版本中,装饰器是一个需要确定的对象,它不支持一些表达式的计算的场景,也不支持匿名函数作为装饰器,举 2 个例子:

In : from dataclasses import dataclass
...: d = [dataclass]
...:
...: @d[0]
...: class A:
...:     attr: int
...:
...: print(A)
...:
  File "<ipython-input-1-cf77b251b3d6>", line 4
    @d[0]
      ^
SyntaxError: invalid syntax

In : @lambda func: lambda *args: func(*args)+1
...: def plus(a, b):
...:     return a + b
    File "<ipython-input-3-236754e0ed07>", line 1
    @lambda func: lambda *args: func(*args)+1
     ^
SyntaxError: invalid syntax

直接抛语法错误,现在它们都可以正常使用了:

In : from dataclasses import dataclass
...: d = [dataclass]
...:
...: @d[0]
...: class A:
...:     attr: int
...:

In : print(A)
<class '__main__.A'>

In : @lambda func: lambda *args: func(*args)+1
...: def plus(a, b):
...:     return a + b
...:

In : plus(1, 2)
Out: 4

总结

这个版本实在没有让我激动的新特性。