社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 3.8 一周后发布,这几个特性值得关注

编程派 • 4 年前 • 716 次点击  

后台回复【入门资料

送你十本Python电子书



文 | EarlGrey

推荐 | 编程派公众号(ID:codingpy)


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

海象运算符 :=

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

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

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

  1. m = re.match(p1, line)

  2. if m:

  3. return m.group(1)

  4. else:

  5. m = re.match(p2, line)

  6. if m:

  7. return m.group(2)

  8. else:

  9. m = 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-16 16:58:00.680222

仅位置参数(position-only)

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

下面这个例子中,参数 ab 只能是位置参数,而 cd 可以是位置参数,也可以是关键字参数, ef 则要求是关键字参数:

  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. r = 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. 10 20 {'a': 1, 'b': 2, 'c': 3}

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

  1. class Counter(dict):


  2. def __init__(self, iterable=None, /, **kwds):

  3. # Note "iterable" is a possible keyword argument


参考链接:

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

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


回复下方「关键词」,获取优质资源


回复关键词「 pybook03」,立即获取主页君与小伙伴一起翻译的《Think Python 2e》电子版

回复关键词「入门资料」,立即获取主页君整理的 10 本 Python 入门书的电子版

回复关键词「book 数字」,将数字替换成 0 及以上数字,有惊喜好礼哦~


推荐阅读



题图:pexels,CC0 授权。

告诉朋友们,好文我在看
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/46445
 
716 次点击  
文章 [ 1 ]  |  最新文章 3 年前