PEP 3129 – 类装饰器
- 作者:
- Collin Winter <collinwinter at google.com>
- 状态:
- 最终
- 类型:
- 标准跟踪
- 创建:
- 2007年5月1日
- Python 版本:
- 3.0
- 历史记录:
- 2007年5月7日
摘要
本 PEP 提出类装饰器,是对 PEP 318 中引入的函数和方法装饰器的扩展。
基本原理
当最初讨论将函数装饰器纳入 Python 2.4 时,由于元类的原因,类装饰器被认为是 模糊且不必要的。在使用 Python 2.4.x 系列版本积累了几年的经验,并且对函数装饰器及其用途的熟悉度日益提高之后,BDFL 和社区重新评估了类装饰器,并建议将其纳入 Python 3.0 [1]。
其动机用例是使某些结构更容易表达,并且不那么依赖于 CPython 解释器的实现细节。虽然可以使用元类表达类似类装饰器的功能,但结果通常令人不快,并且实现非常脆弱 [2]。此外,元类是继承的,而类装饰器不是,这使得元类不适合某些特定于单个类的类装饰器用途。像 Zope 这样的大型 Python 项目正在经历这些复杂的变通方法来实现类似类装饰器的功能,这说服了 BDFL。
语义
类装饰器的语义和设计目标与函数装饰器相同(PEP 318,PEP 318);唯一的区别是您正在装饰一个类而不是一个函数。以下两个代码片段在语义上是相同的
class A:
pass
A = foo(bar(A))
@foo
@bar
class A:
pass
有关装饰器的详细介绍,请参阅 PEP 318。
实现
使 Python 语法适应类装饰器需要修改两条规则并添加一条新规则
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt |
with_stmt | funcdef | classdef
需要更改为
decorated: decorators (classdef | funcdef)
funcdef: 'def' NAME parameters ['->' test] ':' suite
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt |
with_stmt | funcdef | classdef | decorated
添加 decorated
是必要的,以避免语法中的歧义。
Python AST 和字节码必须相应地修改。
Jack Diederich 提供了一个参考实现 [3]。
接受
在发布此 PEP 后几乎没有讨论,这意味着每个人都同意应该接受它。
该补丁已提交到 Subversion,修订版本为 55430。
参考文献
版权
本文档已进入公有领域。
来源:https://github.com/python/peps/blob/main/peps/pep-3129.rst