PEP 224 – 属性文档字符串
- 作者:
- Marc-André Lemburg <mal at lemburg.com>
- 状态:
- 已拒绝
- 类型:
- 标准跟踪
- 创建日期:
- 2000年8月23日
- Python 版本:
- 2.1
- 发布历史:
引言
本PEP描述了Python 2.0的“属性文档字符串”提案。本PEP跟踪此功能的地位和所有权。它包含对该功能的描述,并概述了支持该功能所需的更改。此文件的CVS修订历史记录包含确切的历史记录。
基本原理
本PEP提议对Python目前处理嵌入在Python代码中的文档字符串的方式进行少量补充。
Python目前仅处理出现在类定义、函数定义之后,或作为模块中第一个字符串字面量的情况。这些字符串字面量被添加到相关对象的__doc__属性下,然后可用于内省工具,这些工具可以提取其中包含的信息,用于帮助、调试和文档目的。
出现在上述位置之外的文档字符串将被简单地忽略,并且不会导致任何代码生成。
这是一个例子
class C:
"class C doc-string"
a = 1
"attribute C.a doc-string (1)"
b = 2
"attribute C.b doc-string (2)"
文档字符串(1)和(2)目前被Python字节码编译器忽略,但显然可以很好地用于记录它们之前的命名赋值。
本PEP提议通过为将其内容添加到它们出现的对象下的新生成的属性名称中来利用这些情况。
这种方法最初的想法(也启发了上述例子)是实现类属性的行内文档,目前只能在类的文档字符串中或使用注释进行文档,而注释不能用于内省。
实施
文档字符串由字节码编译器作为表达式处理。当前的实现特殊处理了上面提到的几个位置以利用这些表达式,但除此之外完全忽略了这些字符串。
为了能够使用这些文档字符串来记录命名赋值(这是定义例如类属性的自然方式),编译器必须跟踪最后赋值的名称,然后使用此名称将文档字符串的内容赋值给包含对象的属性,方法是将其存储为常量,然后在对象构造时将其添加到对象的命名空间中。
为了保留诸如继承和隐藏Python特殊属性(带有前导和尾随双下划线的属性)等功能,必须应用特殊的名称修饰,以唯一标识文档字符串属于名称赋值,并允许稍后通过检查命名空间来查找文档字符串。
以下名称修饰方案实现了上述所有功能
__doc_<attributename>__
为了跟踪最后赋值的名称,字节码编译器将此名称存储在编译结构的一个变量中。此变量默认为NULL。当它看到一个文档字符串时,它会检查该变量,并使用该名称作为上述名称修饰的基础,以生成文档字符串到修饰名称的隐式赋值。然后它将该变量重置为NULL,以避免重复赋值。
如果变量没有指向名称(即为NULL),则不进行赋值。这些将像以前一样继续被忽略。所有经典的文档字符串都属于这种情况,因此不会进行重复赋值。
在上面的例子中,这将导致创建以下新的类属性
C.__doc_a__ == "attribute C.a doc-string (1)"
C.__doc_b__ == "attribute C.b doc-string (2)"
一个针对Python 2.0当前CVS版本实现上述功能的补丁可在SourceForge上获取:[1]。
实现中的注意事项
由于实现不会在处理非表达式(例如函数定义)时重置编译结构变量,因此最后分配的名称将一直保持活动状态,直到下一个分配或下一个文档字符串出现。
这可能导致文档字符串和赋值可能被其他表达式分隔的情况
class C:
"C doc string"
b = 2
def x(self):
"C.x doc string"
y = 3
return 1
"b's doc string"
由于方法“x”的定义目前没有重置所使用的赋值名称变量,当编译器到达文档字符串“b’s doc string”时它仍然有效,因此将字符串赋值给__doc_b__。
解决此问题的一种可能方案是在编译器中为所有非表达式节点重置名称变量。
可能的问题
尽管可能性很小,属性文档字符串可能会意外地与属性的值连接起来
class C:
x = "text" \
"x's docstring"
末尾的斜杠将导致Python编译器连接属性值和文档字符串。
然而,现代语法高亮编辑器很容易使这个意外可见,而且通过简单地在属性定义和文档字符串之间插入空行,你可以完全避免可能的连接,所以这个问题可以忽略不计。
另一个可能的问题是使用三引号字符串作为取消代码部分注释的方式。
如果注释字符串开始之前恰好有一个赋值,那么编译器会将该注释视为文档字符串属性并对其应用上述逻辑。
除了为本来没有文档的属性生成文档字符串之外,没有其他问题。
版权
本文档已置于公共领域。
参考资料
来源:https://github.com/python/peps/blob/main/peps/pep-0224.rst
我们BDFL的评论
Guido对本PEP的早期评论
作者的回复
2001年3月,Guido在Python-dev上对此PEP发表了意见。以下是他通过私人邮件告知本PEP作者的拒绝理由