在 Python 中,我们在类内部定义的变量可以是类变量(也可以称为静态变量)或者实例变量。类变量由类的所有对象共享,而实例变量则是每个对象独有的。
与 Java 或 C++ 等语言不同,Python 并不需要一个 static 关键字。任何直接在类体内部赋值的变量,都会自动成为类变量。
类变量是属于类本身,而不是属于某个特定对象的变量。该类的所有实例都共享这同一个变量副本。
- 定义在类内部,但在所有方法之外
- 可以通过类名或对象来访问
- 内存只分配一次
class Student:
school = "ABC School" # 类变量
s1 = Student()
s2 = Student()
print(s1.school)
print(s2.school)
Output
ABC School
ABC School
解释:
- school 是一个类变量
- s1 和 s2 共享同一个值
- 该变量属于类,而不是单独的某个对象
实例变量是属于特定对象的变量。每个对象都维护着这些变量自己的副本。
- 定义在方法内部(通常是在 init() 中)
- 对于每个对象来说是唯一的
- 修改操作只影响该特定对象
class Student:
def __init__(self, name):
self.name = name # 实例变量
s1 = Student("Jake")
s2 = Student("Emily")
print(s1.name)
print(s2.name)
Output
Jake
Emily
解释:
- name 是一个实例变量
- 每个对象都有自己的值
- 改变一个对象的值不会影响另一个对象
示例:类变量 vs 实例变量
这个示例向我们展示了类变量是如何被共享的,以及实例变量是如何保持独立的。
class CSStudent:
stream = ‘cse‘ # 类变量
def __init__(self, name, roll):
self.name = name # 实例变量
self.roll = roll # 实例变量
# 创建对象
a = CSStudent(‘Rose‘, 1)
b = CSStudent(‘Nat‘, 2)
print(a.stream)
print(b.stream)
print(a.name)
print(b.name)
Output
cse
cse
Rose
Nat
解释:
- stream 被所有对象共享
- name 和 roll 对于每个对象是唯一的
- 两个对象访问的是同一个类变量
修改类变量
我们可以通过两种方式来修改类变量。然而,只推荐其中一种方法,因为它能避免混淆。
通过实例修改(不推荐)
a.stream = ‘ece‘
print(a.stream)
print(b.stream)
Output
> ece
> cse
当我们使用对象(a.stream)来改变类变量时,Python 实际上并没有改变那个类变量。相反,它仅为对象 a 创建了一个新的实例变量。所以:
- a 获得了它自己的 stream = ‘ece‘
- b 仍然使用原始的类变量值 cse
这可能会让人感到困惑,因为它看起来像是类变量被改变了,但实际上并没有。
通过类名修改(推荐)
CSStudent.stream = ‘mech‘
print(a.stream)
print(b.stream)
Output
> ece
> mech
当我们使用类名来修改变量时,类变量才真正被更新了。所有没有自己实例变量的对象都会反映出这个变化。在这里:
- b 显示了更新后的值 mech
- a 仍然显示 ece,因为它已经有了自己的实例变量