Python高级特性(三)——实例变量与类变量

一、区别类变量和实例变量

类变量在类定义的内部声明(位于实例方法之外),不受任何特定类实例的束缚。类变量将其内容存储在类本身中,从特定类创建的所有对象都可以访问同一组类变量。修改类变量会同时影响所有对象实例。
实例变量绑定到特定的对象实例上,它的内容不存储在类上,而是存储在每个由类创建的单个对象上。因此实例变量的内容与每个对象实例相关,修改实例变量只会影响对应的对象实例。

二、代码解释

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。

你可能感兴趣的:(Python高级特性)