全面详解 Python 类变量与实例变量的访问步骤
·
在 Python 中,类变量和实例变量是面向对象编程的核心概念,它们的访问方式和作用域存在显著差异。以下从定义、访问场景、优先级等方面全面详解两者的访问步骤:
一、核心概念
- 类变量:定义在类中、方法外的变量,属于类本身,被所有实例共享。
- 实例变量:定义在实例方法(通常是
__init__)中,通过self.变量名声明,属于单个实例,不共享。
二、类变量的访问步骤
类变量可通过 类名 或 实例对象 访问,具体步骤如下:
1. 通过类名访问(推荐)
直接使用 类名.类变量名 访问,步骤:
- 解析类名,找到对应的类对象。
- 在类对象的命名空间中查找目标变量。
- 若存在,返回变量值;若不存在,抛出
AttributeError。
示例:
python
运行
class Student:
school = "北京大学" # 类变量
# 访问步骤:Student → 查找 school → 返回 "北京大学"
print(Student.school) # 输出:北京大学
2. 通过实例对象访问
使用 实例名.类变量名 访问,步骤:
- 先在实例对象的命名空间中查找目标变量。
- 若未找到,向上查找实例所属的类的命名空间。
- 若类中存在,返回类变量值;否则抛出
AttributeError。
示例:
python
运行
stu1 = Student()
# 访问步骤:stu1 的命名空间(无 school)→ 查找 Student 类 → 找到 school → 返回 "北京大学"
print(stu1.school) # 输出:北京大学
三、实例变量的访问步骤
实例变量只能通过 实例对象 访问,步骤:
- 解析实例名,找到对应的实例对象。
- 在实例对象的命名空间(
__dict__)中查找目标变量。 - 若存在,返回变量值;若不存在,抛出
AttributeError(不会去类中查找)。
示例:
python
运行
class Student:
def __init__(self, name):
self.name = name # 实例变量
stu1 = Student("张三")
# 访问步骤:stu1 → 查找 name → 返回 "张三"
print(stu1.name) # 输出:张三
# 错误:实例变量不能通过类名访问
print(Student.name) # 报错:AttributeError: type object 'Student' has no attribute 'name'
四、访问优先级与覆盖问题
当实例变量与类变量同名时,实例变量会覆盖类变量(仅对当前实例有效),访问步骤如下:
- 通过实例访问时,优先返回实例变量(实例命名空间存在该变量)。
- 通过类名访问时,仍返回类变量(类命名空间的变量未被修改)。
示例:
python
运行
class Student:
school = "北京大学" # 类变量
stu1 = Student()
stu1.school = "清华大学" # 给 stu1 绑定实例变量(与类变量同名)
# 实例访问:优先实例变量
print(stu1.school) # 输出:清华大学(实例变量)
# 类访问:仍为类变量
print(Student.school) # 输出:北京大学(类变量)
五、修改变量的注意事项
-
修改类变量:
- 必须通过
类名.类变量名 = 新值,否则会变成给实例绑定新的实例变量。
python
运行
Student.school = "浙江大学" # 正确修改类变量,所有实例共享新值 stu1.school = "南京大学" # 错误:仅给 stu1 新增实例变量,不影响类和其他实例 - 必须通过
-
修改实例变量:
- 只能通过
实例名.实例变量名 = 新值,直接修改实例的命名空间。
- 只能通过
六、总结访问步骤对比
| 变量类型 | 访问方式 | 查找顺序(优先级) | 是否共享 |
|---|---|---|---|
| 类变量 | 类名 / 实例名 | 实例命名空间 → 类命名空间 | 是 |
| 实例变量 | 仅实例名 | 仅实例命名空间(不查类) | 否 |
通过理解以上步骤,可以清晰区分类变量和实例变量的访问逻辑,避免因作用域混淆导致的错误。
更多推荐
所有评论(0)