当我们在Python中定义一个类时,即我们是该类的作者时,
我们是否允许创建一个类的属性,其名称以双下划线开头和结尾,并且不与特殊属性冲突,例如__base__, __class__, __name__, __dict__
和特殊方法,例如__new__, __init__, __str__, __repr__, __hash__, __call__, __get__
?
如果是,我们定义的此类属性(例如__madeupAttribute__
)的查找是否与查找这些特殊属性相同?请注意,这些特殊属性的查找过程与常规属性的查找过程(例如attribute1
,attribute2
)不同,正如Python中的Nutshell所述
一些属性dunder-names是特殊的,
C.__name__
,C.__bases__
,x.__class__
。当您使用其中一个引用属性时 这些特殊的名称,属性引用直接看到了一个专用的插槽 类或实例对象并获取它在那里找到的值。你不能解开这些 属性。
我们是否允许创建类的属性,其名称以单个下划线开头?
我们是否允许创建一个类的属性,其名称以两个下划线开头?
请注意,我已阅读What is the meaning of a single- and a double-underscore before an object name?。我在这篇文章中的问题是:Python类的作者可以创建什么类型的属性,什么不可以。
感谢。
答案 0 :(得分:1)
我们是否允许创建一个类的属性,其名称都是 以双下划线开头和结尾,不与特殊冲突 属性?如果是,我们定义的这些属性(例如
__madeupAttribute__
)的查找是否与查找这些特殊属性相同?
如果您创建一个名称在两边都有双下划线的属性,则无需任何特殊处理。只有语言保留的属性名称才有特殊的查找处理。其中一些可能会或可能不会由类作者直接创建。大多数用于负责实现对该类对象的操作的方法的名称,例如__add__
,__mul__
都可以自由写入。其他的,将在类创建时被覆盖,但之后可以自由更改,例如__name__
,而其他人与类一起创建并且是可模仿的,例如__mro__
。文档中未列出的名称与普通名称相同,但可能与添加到语言对象模型中的未来特殊名称冲突。您将能够在language data model中找到大多数特殊属性和方法名称,尽管有些属性可以由特定的stdlib模块使用,而不是在那里列出。 (它们对于该语言也没有特殊含义,仅适用于该模块。一个例子是__reduce__
,由pickle
使用)
我们是否允许创建一个类的属性,其名称以单个下划线开头?
是 - 单个下划线对Python没有特殊意义,它只是一个约定,在类/包之外创建以下划线开头的任何内容的代码不应该直接更改它或依赖于它的值或它的存在。此约定取代了在其他语言中使用的“私有”属性和名称
我们是否允许创建一个类的属性,其名称以两个下划线开头?
对于以两个下划线为前缀的类的属性,在 compile 时有一个特殊的处理方法,它会破坏这些名称,将类的名称烘焙到属性名称本身。在类体内编写的所有代码(包括内部方法,以及嵌套函数内部的这些方法)都以相同的方式更改。此名称修改使得从该类继承的类(如果它们在其代码中使用相同的属性名称),该属性将不会与父类的属性发生冲突和独立。此功能可用于为您不希望派生类读取或写入的属性提供封装,但同样更多是由于约定和方便,因为名称修改规则是众所周知的。早期的Python文档经常暗示这应该用于“私有属性”。这有点不正确:Python中的“私有”仅限于惯例,出于可读性目的,通常依赖于单个带前缀的下划线。