详解Python 类变量与实例变量的陷阱

  • Post category:Python

Python中,类变量是所有实例共享的变量,它们定义在类中且不属于任何一个方法。而实例变量是每个实例独有的变量,它们定义在实例化时在__init__方法中初始化。

但是类变量与实例变量的使用中有一些陷阱需要注意:

1. 类变量与实例变量同名

当实例变量与类变量同名时,实例变量会覆盖类变量,并且不会对其他实例的类变量造成影响。

class Person:
    name = ""

    def __init__(self, name):
        self.name = name

p1 = Person("Tom")
p2 = Person("Jerry")

print(p1.name) # Tom
print(p2.name) # Jerry
print(Person.name) # ""

2. 类变量在修改时会影响所有实例

当修改类变量时,会影响所有已创建的实例。

class Person:
    count = 0

    def __init__(self, name):
        self.name = name
        Person.count += 1

p1 = Person("Tom")
p2 = Person("Jerry")

print(p1.count) # 2
print(p2.count) # 2
print(Person.count) # 2

这时如果想让实例独立地使用类变量,可以通过在__init__方法中初始化同名实例变量来避免影响其他实例。

class Person:
    count = 0

    def __init__(self, name):
        self.name = name
        self.count = 0
        Person.count += 1

p1 = Person("Tom")
p2 = Person("Jerry")

print(p1.count) # 0
print(p2.count) # 0
print(Person.count) # 2

关于Python类变量与实例变量的使用方法,可以参考以下完整攻略:

定义类变量

类变量在类中定义,通常与方法平级,使用class关键字加上变量名和初始值进行定义。

class Person:
    count = 0

定义实例变量

实例变量通常在__init__方法中定义,在实例化时进行初始化。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

类变量与实例变量的区别

类变量是所有实例共享的,而实例变量是每个实例独有的。

修改类变量

类变量可以通过类名进行修改、获取,修改后所有实例都可以访问到修改后的值。

Person.count = 10

修改实例变量

实例变量可以直接通过实例名进行修改、获取,修改后只有该实例可以访问到修改后的值。

p1 = Person('Tom', 20)
p1.age = 30

示例1

class Car:
    count = 0

    def __init__(self, name, color):
        self.name = name
        self.color = color
        Car.count += 1

c1 = Car('Benz', 'red')
c2 = Car('BMW', 'green')

print(c1.count) # 2
print(c2.count) # 2
print(Car.count) # 2

示例2

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

dog1 = Dog('Tom', 3)
dog2 = Dog('Jerry', 5)

dog1.gender = "male" # 可以动态增加实例变量
dog2.gender = "female"

print(dog1.name, dog1.age, dog1.gender) # Tom 3 male
print(dog2.name, dog2.age, dog2.gender) # Jerry 5 female