文档章节

Python 3.9 新特性:任意表达式可作为装饰器!

豌豆花下猫
 豌豆花下猫
发布于 03/20 17:46
字数 1549
阅读 9.4K
收藏 3

一个月前(2月20日),一则新的 PEP 没有受到任何阻碍就被官方采纳了,这么快的速度,似乎并不多见。

然而,更为高效率的是,仅在半个月内,它的实现就被合入了代码仓。也就是说,我们最快有望在 3 天后(3月23日)发布的 3.9.0 alpha 5 版本中看到它!

Python 3.9 的发布计划:

这个 PEP 就是 PEP-614:放宽对装饰器的语法限制。

当前装饰器的语法为:

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE

PEP-614 提议将其简化为:

decorator: '@' namedexpr_test NEWLINE

我已经把 PEP 全文翻译出来了,Github 地址:http://dwz.date/RV9

放宽对装饰器的限制,这对之前的用法没有影响,但至于会带来哪些新的好处,我还不知道有哪些现实的例子。

下面是 PEP 翻译后的核心内容摘录,先跟大家一睹为快吧:

--------------摘录分割线----------------

概要

Python 当前要求所有装饰器都由 dotted name 组成,可选地带一个调用。本 PEP 提议消除这些限制,并允许任何有效的表达式作为装饰器。

(译注:dotted name,指的是装饰器在“@”符号后是“xxx”或“xxx.yyy”这种格式。没有很好地译法,故未译。)

动机

在最初引入装饰器时,Guido表示对其语法作限制是一种偏好,而不是因为技术的要求:

> 我对此有一种直觉。我不确定它来自哪里,但我就是有……因此,尽管将来将语法更改为 @test 相当容易,但我仍想坚持使用更受限的形式,除非给出了真正的使用 @test 会增加可读性的用例。

尽管在实践中很少遇到问题,但是多年来,BPO问题邮件列表帖子不断出现,要求去除限制。最近的一封邮件(它促成了本提案)提供了一段很好的使用 PyQt5 库的示例代码,如果放宽现有的限制,它将变得更具可读性、地道性和可维护性。

稍作修改的示例:

buttons = [QPushButton(f'Button {i}') for i in range(10)]

# Do stuff with the list of buttons...

@buttons[0].clicked.connect
def spam():
    ...

@buttons[1].clicked.connect
def eggs():
    ...

# Do stuff with the list of buttons...

当前,这些装饰必须重写成这样(译注:上方是假想的最优写法,但 Python 还不支持,只能用下方的啰嗦写法):

button_0 = buttons[0]

@button_0.clicked.connect
def spam():
    ...

button_1 = buttons[1]

@button_1.clicked.connect
def eggs():
    ...

此外,当前的语法太过宽松,以至于无法将更复杂的装饰器表达式结合在一起。也就是说,当前的限制并没有像预期的那样去禁止任意复杂的表达式,而是使它们变得更丑陋且效率低下:

# Identity function hack:

def _(x):
    return x

@_(buttons[0].clicked.connect)
def spam():
    ...

# eval hack:

@eval("buttons[1].clicked.connect")
def eggs():
    ...

原理

允许任意表达式

在相当长的一段时间内,允许任意有效表达式的决定(而不仅仅是放宽当前的限制,如允许取下标),已被视为装饰器语法发展的下一个顺理成章的步骤。正如Guido 在另一个邮件列表讨论中所说

> 我觉得强制约束它没有什么道理,因为它已不再是一个普通的表达式。

若对语法进行特殊设置以允许某些有用的用法,只会使当前情况复杂化,并且几乎能肯定此过程会在将来的某个时间重复。此外,这种语法上的改变的目的之一是阻止使用上述的 eval 和反模式的 identity-function 之类的诱惑。

简而言之:如果要删除一些限制,我们应该删除所有限制。

什么算一个“表达式”

在本文档中,“表达式”一词的用法与《Python语言参考》中定义的相同。可以概括为“任何在 if、elif 和 while 块中测试为有效的内容”。

这与可能更流行的定义稍有不同,后者可以概括为“任何作为有效字符串输入给 eval 的内容”。

前一个“表达式”的定义更方便,因为它非常贴合我们的需求,并且可以重用被现有语言结构所允许的语法。与其它定义相比,它有两个细微的差异:

1、元组必须加括号

这是基于 Guido 在同一封邮件中的洞察。紧接着前面的引述:

> 但是我不会允许逗号,决不可能赞成这样: > > python > @f, g > def pooh(): ... >

确实,它可能甚至导致没有经验的读者得出结论,认为正在使用多个装饰器,就像它们被堆叠了一样。这里要求加括号,可以使意图变得清晰,而无需施加进一步的限制和复杂语法。

2、赋值表达式不需括号

在这里,语法的选择是明确的。PEP 572解释了为什么需要在顶级表达式语句的周围加上括号:

> 加入此规则是为了简化用户在赋值语句和赋值表达式之间的选择——没有令两者都生效的语法位置。

由于赋值语句在此处无效,因此赋值表达式就不必带括号。

(译注:赋值表达式,即 Assignment Expressions 或 Named Expressions,是 Python 3.8 引入的新特性,就是它引入了新的“:=”海象操作符。)

-----------------正文分割线---------------

PEP 的全文翻译已收录在 Github 的《PEP中文翻译计划》中,目前已有 20+ 篇 PEP 翻译,欢迎感兴趣的同学查阅&参与翻译。

附录:

PEP614英文:https://www.python.org/dev/peps/pep-0614/

PEP614中文:http://dwz.date/RV9

PEP中文翻译计划:https://github.com/chinesehuazhou/peps-cn

© 著作权归作者所有

豌豆花下猫
粉丝 76
博文 80
码字总数 205939
作品 0
苏州
私信 提问
加载中

评论(7)

其乐m
其乐m
我想问下博客是怎样置顶的,最近才入开源,有点不懂
豌豆花下猫
豌豆花下猫 博主
发布文章时,底部就有可以勾选置顶
W
WindSpeed
皆大欢喜
PynixWang
PynixWang
@a
@b
@c
@d
@d
@e
@f
@g
def h:
pass
YhIcYt
YhIcYt
hahahaha
PynixWang
PynixWang
现在可以
PynixWang
PynixWang
@(a,b,c,d,e,f,g) def h: pass 这样了
第20天:Python 之装饰器

by 轩辕御龙 Python 之装饰器 1. 概念介绍 装饰器(decorator),又称“装饰函数”,即一种返回值也是函数的函数,可以称之为“函数的函数”。其目的是在不对现有函数进行修改的情况下,实现...

纯洁的微笑
2019/09/22
0
0
Python 3.8正式发布,带来那些新特性? - 知乎

本文首发于微信公众号「Python之美」:https://mp.weixin.qq.com/s/RpvtevM3Hzfk1hv0xXVLtw 今天Python3.8发布啦,我们一起看看这个版本都添加了那些新功能和特性。 PEP 572: Assignment Expr...

Python之美
2019/10/21
0
0
Python 简单入门指北(二)

Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值。总而言之,函数和普通变量并没...

李洪强
2017/12/05
0
0
Python - 进阶(持续更新 ing)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/qq39437555/article/details/93867588 文章目录 Python - 面向对象 ...

桃子味儿的汽水~
2019/08/23
0
0
Python第六章-函数06-高阶函数

函数的高级应用 二、高阶函数 高级函数, 英文叫 Higher-order Function. 那么什么是高阶函数呢? 在说明什么是=高阶函数之前, 我们需要对函数再做进一步的理解! 2.1 函数的本质 函数的本质是什...

平仄平仄平平仄
04/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

基于 rsync 和 ln 实现“写时复制”的快照备份功能

一、基本原理 这里“写时复制”加了一个引号,因为这是专门针对使用rsync备份时的写时复制效果,而不是事实上的写时复制(copy-on-write),其达到的目的如下: 使用 rsync 备份数据后,立即...

Inpool
21分钟前
17
0
郑州哪哪里可以开工程款发票-郑州_新闻网

【电薇同步;1.3.8 - 2.7.4.1 - 5.2.9.7.】张生、诚、信、合、作,保、真、售、后、保、障、长、期、有、效。adb的全称为Android Debug Bridge,是Android手机通用...

yyqqvip
今天
30
0
Nginx 反向代理访问

在Nginx 配置 server { listen 80; server_name www.xiaocx.org www.xiaocx.org www.xiaocx.org; root /Users/maison/work/xiaocx/dist; index i......

韩庚庚
今天
33
0
python笔记:环境变量已设置CMD中一直报错"python"不是内部命令,也不是可运行的程序或批处理文件

这些天虽然也写了几个小工具,但是打包都是在anaconda prompt中完成的,因为CMD中一直报错"python"不是内部命令,也不是可运行的程序或批处理文件,各种查度,千篇一律的是环境变量配置的问题...

小玲_001
今天
13
0
AI+BI服务模式

术语与缩写解释 缩写、术语 解 释 BI 商业智能(Business Intelligence,简称:BI),又称商业智慧或商务智能,指用现代数据仓库技术、线上分析处理技术、数据挖掘和数据展现技术进行数据分析...

zoegu228
今天
28
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部