Python中的类变量和实例变量问题

时间:2011-01-17 22:59:09

标签: python instance-variables class-variables

当我有这个类时,变量'value'是类变量。

class Hello:
    value = 10
    def __init__(self):
        print 'init'

我有一个对象'h',我可以为Hello.value和h.value获得相同的'10'值。

h = Hello()
print Hello.value
print h.value

当我运行此命令时,

h.value = 20

当我运行它时,我得到值'10'和'20'。

print Hello.value
print h.value

为什么会这样?

  • Q1:为什么'print h.value'打印出Hello.value的值,而不是引发错误?
  • Q2:h.value = 20是否引入了类似'self.value = 20'的新变量?
  • 问题3:有没有办法阻止创建实例变量(或阻止运行代码'h.value = 20')?

2 个答案:

答案 0 :(得分:4)

这就是Python中属性查找的工作原理:

  1. 如果在实例的字典中找不到属性,则在其类的字典中查找它,如果在那里找不到它,也在基类的字典中查找

  2. 如果您分配给实例属性,这将始终只影响实例 - 即如果属性已存在于实例中则更新属性,或者如果不存在则在实例的字典中创建属性。

  3. 如果您不喜欢此行为,则可以覆盖__setattr__()方法以执行任何操作 - 例如,如果您不想允许创建实例属性,则抛出错误。后者也可以通过向班级添加__slots__ = []来实现。

答案 1 :(得分:4)

如果Python查找o.attr,它首先检查对象实例,然后检查其类,然后检查基类,依此类推。它对方法和数据属性都这样做(即数据和代码属性之间没有区别)。

在赋值时,值始终分配给实例。所以

  • A1。因为它倒退了 class(必须这样,因为方法 否则不会起作用)

  • A2。是的,确实如此。

  • A3。您可以定义__setattr__ 引发异常的方法。