Python 3.9 有哪些新特性

又到了推出Python新版本的时候啦~我们已经看到 Python 3.9.1 的完整版本。一些最新特性非常惊艳,我们将介绍以下内容:

—— 看看Python最新版本中包含的最佳特性吧

  • 字典合并运算符
  • 类型提示
  • 两种新的字符串方法
  • 新的Python解析器(这一点很酷)

让我们首先看看这些新特性以及如何使用它们。

字典合并(Dictionary Unions)

我最喜欢的新特性之一,其具有优美的语法。如果我们有两个字典a和b需要合并,那么我们现在使用合并运算符。

我们有merge运算符| :

a = {1: 'a', 2: 'b', 3: 'c'}
b = {4: 'd', 5: 'e'}c = a | b
print(c)

[Out]: {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'

还有update运算符|=,它可以更新原始字典:

a = {1: 'a', 2: 'b', 3: 'c'}
b = {4: 'd', 5: 'e'}a |= b
print(a)

[Out]: {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

如果两个字典具有一个公共键(common key), 那么将使用第二个字典中的键值对:

a = {1: 'a', 2: 'b', 3: 'c', 6: 'in both'}
b = {4: 'd', 5: 'e', 6: 'but different'}

print(a | b)

[Out]: {1: 'a', 2: 'b', 3: 'c', 6: 'but different', 4: 'd', 5: 'e'}

利用可迭代对象(Iterables)更新字典

|= 运算符的另一个很酷的特性是能够使用可迭代的对象(比如列表或生成器)来用新的键值对更新字典:

a = {'a': 'one', 'b': 'two'}
b = ((i, i**2) for i in range(3))

a |= b
print(a)

[Out]: {'a': 'one', 'b': 'two', 0: 0, 1: 1, 2: 4}

如果我们使用标准的合并运算符 | 尝试相同的操作,则会得到TypeError,因为它只允许dict类型之间的合并。

Python 3.9 有哪些新特性

类型提示(Type Hinting)

Python 是动态类型的,这意味着我们无需在代码中指定数据类型。

虽然可以这样,但有时可能会造成混淆,突然间 Python 的灵活性变得比什么都麻烦。

从Python 3.5开始,我们可以指定类型,但是相当麻烦。这次更新确实改变了这一点,让我们举个例子:

Python 3.9 有哪些新特性
没有类型提示 (左) 对比Python 3.9的类型提示 (右)

在我们的add_int函数中,我们显然是想为参数加上一个与自身相同的数值(出于某种神秘的不确定原因)。但是我们的编辑器并不知道这一点,而且使用 + 将两个字符串加在一起是完全可以的,因此不会给出警告。

现在我们可以将预期的输入类型指定为int。由此,编辑器就会立即发现问题。

我们也可以非常详细地了解所包含的类型,例如:

Python 3.9 有哪些新特性

类型提示可以用在任何地方,而且由于新的语法,它现在看起来更简明了:

Python 3.9 有哪些新特性
我们指定sum_dict的参数为dict,返回值为int。在测试定义期间,我们也会确定它的类型。

字符串方法(String Methods)

虽然不如其他新特性那么亮眼,但仍然值得一提,因为特别有用。增加了两个新的用于删除前缀和后缀的字符串方法:

"Hello world".removeprefix("He")
[Out]: "llo world"
Hello world".removesuffix("ld")
[Out]: "Hello wor"

方便吧?

新的解析器(New Parser)

这更像是一个隐藏变化,但有可能成为Python未来发展中最重要的变化之一。

Python先前使用的主要是基于LL(1)的语法,而该语法又可以由LL(1)解析器进行解析,该解析器自上而下、从左到右地解析代码,并且仅预读一个token。

我如今几乎不知道它是如何工作的,但是我可以列举一些由于使用这个方法而在Python中产生的问题:

  • Python包含非LL(1)语法;因此,先前语法的某些部分使用了变通方法(workarounds),造成了不必要的复杂性。
  • LL(1)在Python语法中产生了局限性(没有可行的workarounds)。这个问题突显了以下代码根本无法使用先前的解析器来实现(引发 SyntaxError):
with (open("a_really_long_foo") as foo,
      open("a_really_long_bar") as bar):
    pass
  • LL(1)在解析器中以左递归的方式断句。意味着特定的递归语法会在解析树中导致无限循环。Python之父Guido van Rossum 在此解释了这个问题。

所有这些因素(以及我无法理解的许多其他因素)都对 Python 具有重大影响;它们限制了Python的发展。

基于PEG的新解析器将为Python开发者提供更大的灵活性——我们将从Python 3.10开始注意到这一点。

这就是我们可以期待即将到来的Python 3.9的一切。如果你真的等不及了,可以下载最新的3.9.1。

本文来自腾讯云计算社区,转载请注明出处:https://computeinit.com/archives/2896

发表评论

登录后才能评论
交流群