类变量在类定义的内部声明(位于实例方法之外),不受任何特定类实例的束缚。类变量将其内容存储在类本身中,从特定类创建的所有对象都可以访问同一组类变量。修改类变量会同时影响所有对象实例。
实例变量绑定到特定的对象实例上,它的内容不存储在类上,而是存储在每个由类创建的单个对象上。因此实例变量的内容与每个对象实例相关,修改实例变量只会影响对应的对象实例。
class Dog:
num_legs = 4 # 类变量
def __init__(self, name):
self.name = name # 实例变量
if __name__ == '__main__':
jack = Dog('Jack')
jill = Dog('Jill')
# 修改类变量,所有对象都会受影响
Dog.num_legs = 10
print(jack.num_legs, jill.num_legs)
# 若想只修改其中一个对象,需要添加实例变量
Dog.num_legs = 4
print(jack.num_legs, jill.num_legs)
jack.num_legs = 10
print(jack.num_legs, jill.num_legs)
# 这里的示例对象覆盖的类对象
print(jack.num_legs, jack.__class__.num_legs)
输出:
10 10
4 4
10 4
10 4
类Dog含有一个类变量num_legs=4
,我们修改它的值为10,所有对象的该变量都变化。如何只想修改一个对象的变量,必须得另外添加实例变量来覆盖对应的类变量。类变量的调用方式为jack.__class__.num_legs
有一个类变量,需要实现类被实例化的次数,如下代码所示
class CountClass:
num_instance = 0
def __init__(self):
self.__class__.num_instance += 1
if __name__ == '__main__':
for i in range(10):
print(CountClass().num_instance)
正确的输出如下:
1
2
3
4
5
但很不幸的是,在编码过程中没有调用类对象
class CountClass:
num_instance = 0
def __init__(self):
self.num_instance += 1
输出如下:
1
1
1
1
1
每次在实例化对象的时候,都会生成一个新的实例对象,将类对象覆盖,而真正的类对象根本没有任何修改。
所以,在实际操作中千万不能混淆这两种对象,不然就会造成奇怪的bug。