???? “Python貓” ,一個值得加星標的公衆號
花下貓語:好久沒翻譯文章了,但是這個系列我一直放在心上。2019 年即將完結,到新年之初,也許會有些空閒日子,我打算翻譯幾篇(有 PEP 也有別的)。這篇類裝飾器的 PEP 很短,先開個頭吧。
劇照 | 《大明風華》
PEP原文: https://www.python.org/dev/peps/pep-3129
PEP標題: Class Decorators
PEP作者: Collin Winter
創建日期: 2007-05-01
合入版本: 3.0
譯者:豌豆花下貓
PEP翻譯計劃:https://github.com/chinesehuazhou/peps-cn
摘要
本 PEP 提議推出類裝飾器,它是對 PEP-318 引入的函數與方法(function and method)裝飾器的擴展。
原理闡述
當初討論函數裝飾器是否該在 Python 2.4 中引入時,由於有元類,所以類裝飾器被視爲晦澀且不必要的[1]。但是,在使用 Python 2.4.x 系列發行版本的幾年後,對函數裝飾器及其使用的日益熟悉之後,BDFL 和社區重新評估了類裝飾器,並建議將其包含在 Python 3.0 中[2]。
這個改變的目的是使某些構造更易於表達,並且減少對 CPython 解釋器的實現細節的依賴。儘管可以使用元類來實現類似裝飾器(decorator-like)功能的類,但結果通常令人不快,實現起來也很脆弱[3]。
另外,元類是要繼承的,而類裝飾器則不是,這使得元類不適合類裝飾器的某些特定於類的使用場景。諸如 Zope 之類的大型 Python 項目正在經歷這些瘋狂的扭曲,就爲了取得類裝飾器能做到的成績,這一點反而使 BDFL 青睞上了類裝飾器。
語義
類裝飾器的語義和設計目標與函數裝飾器的語義和設計目標相同([4],[5]);唯一的區別是它在裝飾類而不是函數。以下兩個片段在語義上是相同的:
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 提供了參考實現[6]。
驗收
在發佈此 PEP 之後,幾乎沒有討論,這意味着每個人都覺得應該接受它。補丁已提交給 Subversion,版本爲 55430。
參考資料
[1] http://www.python.org/dev/peps/pep-0318/#motivation
[2] https://mail.python.org/pipermail/python-dev/2006-March/062942.html
[3] https://mail.python.org/pipermail/python-dev/2006-March/062888.html
[4] http://www.python.org/dev/peps/pep-0318/#current-syntax
[5] http://www.python.org/dev/peps/pep-0318/#design-goals
[6] https://bugs.python.org/issue1671208
版權
本文檔已經放置在公共領域。源文檔:
https://github.com/python/peps/blob/master/pep-3129.txt
優質文章,推薦閱讀:
感謝創作者的好文