访问objectname.attributename时,将按顺序搜索以下对象:
1。
对象本身(objectname.__dict__
或任何Python提供的objectname属性)。
2。
对象的类型(objectname.__class__.__dict__
)。观察到仅搜索__dict__
,这意味着只有用户提供的类属性。换句话说,即使objectname.__bases__
确实存在,objectname.__class__.__bases__
也可能无法返回任何内容。
3。
对象类的基础,它们的基础等等。 (__dict__
)的每个objectname.__class__.__bases__
。不止一个基础不会混淆Python,现在不应该关注我们。需要注意的是,搜索所有碱基直到找到属性。
为了测试我创建这个例子的理论
class Superb(object):
svar=1
class Sub(Superb):
...
class Leaf(Sub):
def __init__(self):
print(Leaf.svar)
lobj=Leaf()
实例创建工作并打印Leaf.svar的值(为1)。 这意味着在解析Leaf.svar时,Python会查看Leaf对象基础的基础,这不是本文中提到的内容。根据文章,搜索对象类(即类型)的基础。我怀疑文章作者犯了什么错误,这肯定是我理解中的一个缺口。有人可以澄清一下。
答案 0 :(得分:3)
这篇文章掩盖了一些细节。当你有这样的问题时,是时候转向一个权威的来源,在本例中是Python语言参考,3.2. The standard type hierarchy部分,其中包含一个表明(我强调)的类的条目:
类具有由字典对象实现的命名空间。类属性引用被转换为此字典中的查找,例如,
C.x
被转换为C.__dict__["x"]
(尽管对于新式类,特别是有许多钩子允许其他方法来定位属性) 。 当在那里找不到属性名称时,属性搜索在基类中继续。
这是描述类的属性查找,而不是类实例,我相信它会解释代码中发生的事情。
为了完整性,以下是关于类实例的下一个条目:
类实例具有作为字典实现的名称空间,该字典是搜索属性引用的第一个位置。当在那里找不到属性,并且实例的类具有该名称的属性时,搜索将继续使用类属性。
我认为“继续使用类属性进行搜索”,意思是“重复为类提供的过程”,即搜索基类。如果没有继承,那么继承将变得不那么有用了!
您链接的文章解释了类实例的属性查找,但它没有说明类的属性查找。因为它没有,它给人的印象是它以相同的方式工作,但事实并非如此。
答案 1 :(得分:0)
我不确定回答你自己的问题是否公平,但是通过一些进一步的阅读,我明白当对象是“阶级”时,规则中会略有修改。因此,在class.attribute的情况下,也会搜索类的基数(以及类的类,即类型)。
因此,应该在中搜索class.attribute
对象属性(即类定义)
对象的基础(classname。 __ base __ 等等)
对象的类型(类的'type')
对象类的基础(即对象)