经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 其他 » 业界动态 » 查看文章
Python 3.8 一周后发布
来源:今日头条  作者:EarlGrey  时间:2019/10/8 9:14:02  对本文有异议

10月1日,Python 3.8rc1 发布,如果没有意外的话 3.8 将于 10 月 14 日正式发布。新版本的变化有很多,但是我觉得可能最常被用到的,是下面这两个新特性:海象运算符和仅位置参数。

海象运算符 :=

海象运算符是 3.8 版本中最引人瞩目的新特性,因其 :=外观而被称为海象运算符(walrus operator)。引入该运算符的是 PEP 572,而也正是由于 PEP 572 被接受过程中的一些不愉快,导致了 Guido van Rossum 因此辞去了 BDFL 的职位。

有了这个运算之后,我们可以在 if 或 while 语句中使用 :=为变量赋值,其目的也是为了简化多模式匹配和非可迭代对象的循环等问题。

比如说,多模式匹配的写法会从:

  1. = re.match(p1, line)
  2. if m:
  3. return m.group(1)
  4. else:
  5. = re.match(p2, line)
  6. if m:
  7. return m.group(2)
  8. else:
  9. = re.match(p3, line)
  10. ...

变成:

  1. if m := re.match(p1, line):
  2. return m.group(1)
  3. elif m := re.match(p2, line):
  4. return m.group(2)
  5. elif m := re.match(p3, line):
  6. ...

而针对非可迭代对象的循环,也可以从:

  1. ent = obj.next_entry
  2. while ent:
  3. ... # process ent
  4. ent = obj.next_entry

变成这样:

  1. while ent := obj.next_entry:
  2. ... # process ent

这可以让程序员更清晰地表达自己的意图。这个功能其实是许多其他语言已经具备的,但是Python中已经缺失近30年。

相较于由它给Python社区带来的变动,这个特性本身带来的变化就不那么明显了。


使用 f-string 调试

Python 3.6 中就加入了 f-string(也被称为格式化字符串),但是在调试输出时的代码写法会显得比较重复:

  1. print(f'foo={foo} bar={bar}')

在 3.8 中,可以改用如下更简洁的写法:

  1. print(f'{foo=} {bar=}')

两种写法的输出是一样的。

此外,还支持使用修饰符来改变输出的类型,比如 !s代表使用str而非repr的输出:

  1. >>> import datetime
  2. >>> now = datetime.datetime.now
  3. >>> print(f'{now=} {now=!s}')
  4. now=datetime.datetime(2019,7,16,16,58,0,680222) now=2019-07-1616:58:00.680222

仅位置参数(position-only)

新引入了一个函数参数语法 /,表示函数的某些参数必须按位置指定,不能用作关键字参数。

下面这个例子中,参数 a和b只能是位置参数,而c或d可以是位置参数,也可以是关键字参数,e或f则要求是关键字参数:

  1. def f(a, b, /, c, d, *, e, f):
  2. print(a, b, c, d, e, f)

可以这样调用该函数:

  1. f(10,20,30, d=40, e=50, f=60)

但是不能这样调用:

  1. f(10, b=20, c=30, d=40, e=50, f=60) # b 不可以是关键字参数
  2. f(10,20,30,40,50, f=60) # e 必须是关键字参数

该语法的一个用处,是支持纯 Python 函数完整地模拟用 C 编写的函数的行为。例如,内置的 pow函数是不接受关键字参数的:

  1. def pow(x, y, z=None, /):
  2. "Emulate the built in pow function"
  3. = x ** y
  4. return r if z is None else r%z

另外一个用处,是在参数名作用不大的情况下避免使用关键字参数。例如,内置的 len函数的标记是len(obj,/),这样可以避免下面尴尬的调用方式:

  1. len(obj='hello') # obj 关键字降低了可读性

还有一个好处,就是支持以后在不破坏客户端代码的前提下修改参数的名称。例如,在 statistics 模块中,未来可能会调整的参数名 dist,如果像下面这样创建函数的话就可以实现:

  1. def quantiles(dist, /, *, n=4, method='exclusive')
  2. ...

由于 / 左侧的参数并没有暴露为关键字,意味着我们后续可以在 kwargds中继续使用该关键字:

  1. >>>
  2. >>> def f(a, b, /, **kwargs):
  3. ... print(a, b, kwargs)
  4. ...
  5. >>> f(10,20, a=1, b=2, c=3) # a 和 b 有两种用法
  6. 1020{'a':1, 'b':2, 'c':3}

这样极大地简化了那些需要接受任意关键字参数的函数的实现。下面是 collections 模块的部分实现,体现了仅位置参数的优势。

  1. class Counter(dict):
  2.  
  3. def __init__(self, iterable=None, /, **kwds):
  4. # Note "iterable" is a possible keyword argument

参考链接:

  • https://lwn.net/Articles/793818/

  • https://docs.python.org/3.8/whatsnew/3.8.html


 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号