Python类实例方法中访问类变量:self.类变量还是类名.类变量?
Python类实例方法中访问类变量的两种方式对比
两种写法都是合法的Python语法,没有绝对的对错,区别完全取决于你的业务需求,二者的核心差异来自Python的属性查找逻辑。
1. 核心行为差异
self.class_variable的查找逻辑
当你通过self访问类变量时,Python会按照「实例属性字典 → 类属性字典 → 父类属性链」的顺序查找对应值:
- 如果当前实例没有定义同名的实例属性,会正常返回类变量的值
- 如果你给
self.class_variable赋值,只会给当前实例新增一个同名的实例属性,不会修改类变量本身,后续这个实例访问该属性都会优先返回自己的实例属性值,不再受类变量变化的影响。
代码示例:
class Employee: location = "south" def describe(self): print(self.location) emp1 = Employee() emp2 = Employee() emp1.describe() # 输出 south emp2.describe() # 输出 south # 给实例赋值同名属性 emp1.location = "north" emp1.describe() # 输出 north(优先用实例自己的属性) emp2.describe() # 输出 south(不受影响) # 修改类变量 Employee.location = "east" emp1.describe() # 输出 north(还是用自己的) emp2.describe() # 输出 east(没有实例属性,用更新后的类变量)
class_name.class_variable的查找逻辑
直接通过类名访问时,会跳过实例属性查找步骤,固定访问当前类的属性值:
- 不管实例有没有定义同名的实例属性,拿到的都是类层面的统一值
- 修改
class_name.class_variable会影响所有没有同名实例属性的实例,以及后续新创建的所有实例。
代码示例:
class Employee: location = "south" def describe(self): print(Employee.location) emp1 = Employee() emp1.location = "north" # 新增实例属性 emp1.describe() # 输出 south(直接访问类变量,忽略实例属性)
2. 选型建议
PEP8没有强制要求必须用哪种写法,实际开发中可以按照下面的规则选择:
- 如果类变量是实例的默认配置,允许个别实例自定义覆盖,选
self.class_variable,比如员工的默认办公地点、商品的默认定价这类场景。 - 如果类变量是类全局的固定状态/统计值,不允许实例覆盖,选
class_name.class_variable,比如员工总人数统计、类的全局配置开关这类场景。 - 如果需要兼容子类继承场景,不想硬写父类名,可以用
self.__class__.class_variable,会自动访问当前实例对应子类的类变量,扩展性更好。
注意:如果你要修改类变量的值,永远不要用
self.class_variable = xxx的写法,这种写法只会生成实例属性,根本不会修改类变量,必须通过类名(或者self.__class__)修改才能生效。
内容的提问来源于stack exchange,提问作者Tahmid Hossain
相关产品推荐
相关产品推荐

