前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 3.8 一周后发布,这几个特性值得关注

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

作者头像
Python数据科学
发布2019-10-14 11:31:08
4220
发布2019-10-14 11:31:08
举报

海象运算符 :=

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

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

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

m = re.match(p1, line)
if m:
    return m.group(1)
else:
    m = re.match(p2, line)
    if m:
        return m.group(2)
    else:
        m = re.match(p3, line)
        ...

变成:

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

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

ent = obj.next_entry()
while ent:
    ...   # process ent
ent = obj.next_entry()

变成这样:

while ent := obj.next_entry():
    ... # process ent

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

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

使用 f-string 调试

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

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

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

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

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

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

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

仅位置参数(position-only)

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

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

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

可以这样调用该函数:

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

但是不能这样调用:

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

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

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

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

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

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

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

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

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

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

class Counter(dict):

    def __init__(self, iterable=None, /, **kwds):
        # Note "iterable" is a possible keyword argument

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python数据科学 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 海象运算符 :=
  • 使用 f-string 调试
  • 仅位置参数(position-only)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档