详解 Python 中类变量与实例变量的访问关键步骤
·
在 Python 中,类变量和实例变量的访问规则是面向对象编程的基础,理解两者的访问步骤和区别至关重要。以下从定义、访问方式、查找顺序三个维度详解关键步骤:
一、核心定义与存储位置
-
类变量
- 定义在类中、方法外,属于类本身,被所有实例共享。
- 存储在类的命名空间(
类名.__dict__)中。
python
运行
class MyClass: class_var = "我是类变量" # 类变量定义 -
实例变量
- 定义在实例方法中(通常是
__init__方法),通过self.变量名赋值,属于单个实例。 - 存储在实例的命名空间(
实例名.__dict__)中。
python
运行
class MyClass: def __init__(self): self.instance_var = "我是实例变量" # 实例变量定义 - 定义在实例方法中(通常是
二、访问关键步骤与规则
1. 访问类变量的步骤
类变量可通过 类名 或 实例名 访问,核心规则:
- 优先从类的命名空间中查找。
步骤拆解:
-
当使用
类名.类变量访问时:直接在类的命名空间(MyClass.__dict__)中查找目标变量,找到则返回,否则报错。 -
当使用
实例名.类变量访问时:- 先检查实例自身的命名空间(
obj.__dict__),若存在同名变量(实例覆盖了类变量),则返回实例变量; - 若实例中无同名变量,再去实例所属的类的命名空间(
MyClass.__dict__)中查找,找到则返回类变量; - 若类中也无,则继续向上查找父类的命名空间(继承链),直至找到或报错。
- 先检查实例自身的命名空间(
2. 访问实例变量的步骤
实例变量只能通过 实例名 访问,核心规则:
- 必须从实例自身的命名空间中查找,类无法直接访问实例变量。
步骤拆解:
-
当使用
实例名.实例变量访问时:- 直接在实例的命名空间(
obj.__dict__)中查找目标变量; - 若存在则返回,否则报错(即使类中存在同名变量,也不会被访问,因为实例变量与类变量是独立的)。
- 直接在实例的命名空间(
-
注意:类名无法访问实例变量,若尝试
类名.实例变量,会直接去类的命名空间查找,若类中无此变量则报错。
三、关键区别与示例验证
python
运行
class MyClass:
class_var = "类变量初始值" # 类变量
def __init__(self):
self.instance_var = "实例变量初始值" # 实例变量
# 1. 访问类变量
print(MyClass.class_var) # 类名访问:直接查类命名空间 → "类变量初始值"
obj = MyClass()
print(obj.class_var) # 实例访问:实例无同名变量,查类命名空间 → "类变量初始值"
# 2. 实例覆盖类变量(仅影响当前实例)
obj.class_var = "实例覆盖的类变量" # 给实例新增同名变量(实例变量)
print(obj.class_var) # 查实例命名空间 → "实例覆盖的类变量"
print(MyClass.class_var) # 类命名空间未变 → "类变量初始值"
# 3. 访问实例变量
print(obj.instance_var) # 实例访问 → "实例变量初始值"
# print(MyClass.instance_var) # 类名访问 → 报错(类中无此变量)
# 4. 修改类变量(影响所有未覆盖该变量的实例)
MyClass.class_var = "修改后的类变量"
obj2 = MyClass()
print(obj2.class_var) # 实例未覆盖,查类命名空间 → "修改后的类变量"
print(obj.class_var) # 实例已覆盖,仍查实例命名空间 → "实例覆盖的类变量"
四、总结关键原则
- 类变量:类和实例均可访问,实例访问时遵循 “实例优先于类” 的查找顺序;修改类变量会影响所有未覆盖它的实例。
- 实例变量:仅实例可访问,类无法直接访问;每个实例的实例变量独立存储,互不影响。
- 命名空间优先级:访问变量时,实例命名空间 > 类命名空间 > 父类命名空间(MRO 顺序)。
掌握这些步骤和规则,可避免因变量访问错误导致的逻辑问题,尤其在处理继承和多实例共享数据时更为重要。
更多推荐
所有评论(0)