前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 3.9 有哪些新特性

Python 3.9 有哪些新特性

作者头像
溪歪歪
修改2021-01-04 10:28:53
1.2K0
修改2021-01-04 10:28:53
举报
文章被收录于专栏:巫山跬步巫山跬步

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

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

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

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

字典合并(Dictionary Unions)

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

我们有merge运算符| :

代码语言:javascript
复制
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运算符|=,它可以更新原始字典:

代码语言:javascript
复制
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), 那么将使用第二个字典中的键值对:

代码语言:javascript
复制
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)更新字典

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

代码语言:javascript
复制
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类型之间的合并。

类型提示(Type Hinting)

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

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

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

没有类型提示 (左) 对比Python 3.9的类型提示 (右)
没有类型提示 (左) 对比Python 3.9的类型提示 (右)

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

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

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

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

我们指定sum_dict的参数为dict,返回值为int。在测试定义期间,我们也会确定它的类型。
我们指定sum_dict的参数为dict,返回值为int。在测试定义期间,我们也会确定它的类型。

字符串方法(String Methods)

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

代码语言:javascript
复制
"Hello world".removeprefix("He")
[Out]: "llo world"

代码语言:javascript
复制
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):
代码语言:javascript
复制
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。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 字典合并(Dictionary Unions)
    • 利用可迭代对象(Iterables)更新字典
    • 类型提示(Type Hinting)
    • 字符串方法(String Methods)
    • 新的解析器(New Parser)
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档