3

当我有这个类时,变量“值”是类变量。

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'的新变量?
  • Q3:有没有办法防止创建实例变量(或防止运行代码'h.value = 20')?
4

2 回答 2

4

这就是 Python 中属性查找的工作方式:

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

  2. 如果您分配给一个实例属性,这将始终只影响该实例——即,如果该属性已存在于该实例中,则更新该属性,否则在该实例的字典中创建该属性。

如果您不喜欢这种行为,您可以覆盖该__setattr__()方法以做任何您喜欢的事情——例如,如果您不想允许创建实例属性,则抛出错误。后者也可以通过添加__slots__ = []类来实现。

于 2011-01-17T23:04:03.087 回答
4

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

在分配时,值总是被分配给实例。所以

  • A1。因为它回退到类(它必须这样做,因为方法在其他情况下不起作用)

  • A2。是的,它确实。

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

于 2011-01-17T23:04:46.333 回答