实例字典和类字典有什么区别
我在阅读关于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__']