实例字典和类字典有什么区别

7 投票
6 回答
11711 浏览
提问于 2025-04-17 15:23

我在阅读关于Python描述符的内容时,看到了一句话:

Python首先会在实例字典中查找成员。如果找不到,它会在类字典中查找。

我对“实例字典”和“类字典”这两个概念感到很困惑。

有没有人能用代码给我解释一下这是什么意思?

我之前一直把它们当成是一样的东西。

6 个回答

2

这些字典是用来在内部表示对象或类的命名空间的方式。

假设我们有一个类:

class C(object):
    def f(self):
        print "Hello!"

c = C()

在这个时候,f 是在类字典中定义的方法(也就是 f in C.__dict__,而 C.f 在 Python 2.7 中被称为一个 未绑定的方法)。

当你调用 c.f() 时,会经历以下几个步骤:

  • 先在 c.__dict__ 中查找 f,结果找不到
  • 然后在 C.__dict__ 中查找 f,这次找到了
  • 接着调用 C.f(c)

现在,让我们来做个小把戏:

def f_french():
    print "Bonjour!"

c.f = f_french

我们刚刚修改了这个对象自己的字典。这意味着,c.f() 现在会打印出 Bounjour!。这并不会影响原来的类的行为,所以其他的 C 的实例仍然会说英语。

6

我想,你可以通过这个例子来理解。

class Demo(object):
    class_dict = {}   # Class dict, common for all instances

    def __init__(self, d):
        self.instance_dict = d   # Instance dict, different for each instance

而且,随时都可以像这样动态地添加实例属性:

demo = Demo({1: "demo"})
demo.new_dict = {}  # A new instance dictionary defined just for this instance

demo2 = Demo({2: "demo2"})   # This instance only has one instance dictionary defined in `init` method

所以,在上面的例子中,demo 实例现在有两个实例字典——一个是在类外添加的,另一个是在 __init__ 方法中添加的。而 demo2 实例只有一个实例字典,就是在 __init__ 方法中添加的那个。

除此之外,这两个实例还有一个共同的字典——类字典。

11

一个实例字典保存了所有分配给这个实例的对象和数值的引用,而类级别的字典则保存了类命名空间下的所有引用。

来看下面这个例子:

>>> class A(object):
...    def foo(self, bar):
...       self.zoo = bar
...
>>> i = A()
>>> i.__dict__ # instance dict is empty
{}
>>> i.foo('hello') # assign a value to an instance
>>> i.__dict__ 
{'zoo': 'hello'} # this is the instance level dict
>>> i.z = {'another':'dict'}
>>> i.__dict__
{'z': {'another': 'dict'}, 'zoo': 'hello'} # all at instance level
>>> A.__dict__.keys() # at the CLASS level, only holds items in the class's namespace
['__dict__', '__module__', 'foo', '__weakref__', '__doc__']

撰写回答