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

  • Post category:Python

Python 类变量与实例变量

什么是类变量和实例变量

在 Python 中,类变量是指定义在类中但在方法之外的变量,类变量是属于整个类的,任何通过该类创建的实例都可以访问到这个变量,且它的值是公共的。实例变量是指定义在方法内或类内但在方法之中、以self.开头的变量,实例变量是属于实例的,通过self访问,它的值会在每个实例之间发生变化。

类变量与实例变量的陷阱

在使用类变量和实例变量时,要特别小心。因为它们具有不同的作用域和生命周期,如果不小心处理可能会引发一些潜在的问题。

以下是一些常见的陷阱:

  1. 修改类变量的值可能会影响到所有类的实例
  2. 直接访问实例变量可能不会得到正确的值
  3. 如果使用类变量来初始化一个实例变量,可能会导致所有实例之间共享相同的值
  4. 如果使用实例变量作为类变量的初始值,可能会导致意外的结果

如何正确地使用类变量和实例变量

访问类变量

使用类名.变量名来引用类变量,或者使用实例名.变量名来引用类变量。在 Python 中,如果实例变量与类变量同名,则会覆盖类变量。

修改类变量

要修改类变量的值,可以使用类名.变量名或者实例名.变量名。但是要注意,如果通过实例名修改类变量,那么只有这个实例会受到影响,其他实例的值不会改变。

访问实例变量

实例变量只能通过实例名.变量名来引用。如果在类的方法中访问实例变量,则必须使用self.变量名来引用。

修改实例变量

要修改实例变量,只能通过实例名.变量名来进行。如果要在类的方法中修改实例变量,则必须使用self.变量名。

示例

以下是两个示例,分别演示了类变量和实例变量的用法。

示例一:使用类变量

class Dog:
    kind = 'canine'
    def __init__(self, name):
        self.name = name

d = Dog('Fido')
e = Dog('Buddy')
print(d.kind)  # 'canine'
print(e.kind)  # 'canine'
print(d.name)  # 'Fido'
print(e.name)  # 'Buddy'

在这个例子中,类变量kind被定义为'canine'。在实例化de之后,可以使用d.kinde.kind引用该变量。由于它是类变量,因此所有类的实例访问到的都是同一个值。

示例二:使用实例变量

class Dog:
    def __init__(self, name):
        self.name = name
        self.tricks = []

    def add_trick(self, trick):
        self.tricks.append(trick)

d = Dog('Fido')
e = Dog('Buddy')
d.add_trick('roll over')
e.add_trick('play dead')
print(d.tricks)  # ['roll over']
print(e.tricks)  # ['play dead']

在这个例子中,tricks被定义为实例变量。在每个实例化后,tricks都是[]。在add_trick方法中,通过self.tricks访问到的是该实例的tricks属性。因此,d.add_trick('roll over')只会修改dtricks属性,而不会影响到etricks属性。