1

根据这篇文章

访问 objectname.attributename 时,依次搜索以下对象的属性:

1. 对象本身(objectname.__dict__或任何 Python 提供的 objectname 属性)。

2. 对象的类型(objectname.__class__.__dict__)。观察 only__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 对象的 base 的 base,这在文章中没有提到。根据文章,搜索对象类(即类型)的基础。我怀疑文章作者是否犯了任何错误,这肯定是我理解上的差距。有人可以澄清一下。

4

2 回答 2

4

这篇文章掩盖了一些细节。当您有这样的问题时,是时候求助于权威来源了,在本例中是 The Python Language Reference,第3.2 节。标准类型层次结构,其中包含一个说明类的条目(我的重点):

一个类有一个由字典对象实现的命名空间。类属性引用被翻译成这个字典中的查找,例如,C.x被翻译成C.__dict__["x"](尽管特别是对于新式类,有许多钩子允许其他定位属性的方法)。如果在那里找不到属性名称,则在基类中继续进行属性搜索

这是描述类的属性查找,而不是类实例,我相信它解释了代码中发生的事情。

为了完整起见,下面是关于类实例的下一个条目,它说:

类实例具有作为字典实现的命名空间,这是搜索属性引用的第一个位置。如果在那里找不到属性,并且实例的类具有该名称的属性,则使用类属性继续搜索。

我将“搜索继续使用类属性”作为“重复为类给出的过程”的意思,即搜索基类。如果没有继承,那么它的用处就更少了!

您链接到的文章解释了类实例的属性查找,但没有说明类的属性查找。因为它没有,它给人的印象是它的工作方式相同,但事实并非如此。

于 2013-04-13T20:20:07.560 回答
1

我不确定回答您自己的问题是否公平,但通过进一步阅读,我了解到当对象是“类”时,规则会略有修改。因此,在 class.attribute 的情况下,还会搜索类的基础(以及类的类,即类型)。

因此应在 class.attribute 中搜索

对象属性(即类定义)

对象的基础(类名。__基础__等等)

对象的类型(在类的情况下为“类型”)

对象类的基础(即对象)

于 2013-04-13T21:10:30.490 回答