Python中通过方法设置类属性时self引用报错的原因与解决
抽象类属性实现问题分析与解决
问题背景
尝试创建包含抽象属性和抽象方法的父类,在子类中通过实例方法的计算值生成抽象属性的内容,但代码执行报错。
原始代码
from abc import ABC from abc import abstractmethod class parent(ABC): @property @abstractmethod def example_variable(self)->str: ... @abstractmethod def example_method(self)->int: ... def __init__(self, foo: int): self.foo = foo class child(parent): def example_method(self)->int: return self.foo + 10 example_variable = f"This is example variable of value {self.example_method()}" if __name__ == "__main__": example_object = child(59) print(example_object.example_variable)
第一次报错信息
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In [7], line 17 14 def __init__(self, foo: int): 15 self.foo = foo ---> 17 class child(parent): 18 def example_method(self)->int: 19 return self.foo + 10 Cell In [7], line 21, in child() 18 def example_method(self)->int: 19 return self.foo + 10 ---> 21 example_variable = f"This is example variable of value {self.example_method()}" NameError: name 'self' is not defined
修改后的代码片段
example_variable = f"This is example variable of value {example_method()}"
第二次报错信息
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In [10], line 17 14 def __init__(self, foo: int): 15 self.foo = foo ---> 17 class child(parent): 18 def example_variable(self)->int: 19 return self.foo + 10 Cell In [10], line 21, in child() 18 def example_variable(self)->int: 19 return self.foo + 10 ---> 21 example_variable = f"This is example variable of value {example_method()}" NameError: name 'example_method' is not defined
报错原因
self的作用域问题:self是实例方法的专用参数,仅在实例方法内部有效。类定义顶层的代码是在类加载阶段执行的,此时没有任何类实例存在,自然找不到self这个名称。- 类加载与实例化的时机差异:类加载时,
example_method只是类中的一个函数对象,并非绑定到实例的方法。直接调用example_method()会因为缺少self参数报错,且此时无法访问实例相关的属性或方法。
正确实现方式
父类中的example_variable是带@property的抽象属性,子类必须用@property装饰器实现该属性的getter方法,在方法内部通过self调用实例方法:
from abc import ABC from abc import abstractmethod class parent(ABC): @property @abstractmethod def example_variable(self)->str: ... @abstractmethod def example_method(self)->int: ... def __init__(self, foo: int): self.foo = foo class child(parent): def example_method(self)->int: return self.foo + 10 @property def example_variable(self)->str: return f"This is example variable of value {self.example_method()}" if __name__ == "__main__": example_object = child(59) print(example_object.example_variable)
代码说明
- 用
@property装饰子类的example_variable方法,使其成为属性,满足父类抽象属性的要求。 - 在getter方法内部,
self代表当前实例,可以正常调用self.example_method()获取计算值,再拼接成字符串返回。 - 访问
example_object.example_variable时,Python会自动触发getter方法,返回动态计算后的结果。
内容的提问来源于stack exchange,提问作者Siddharth Das
相关产品推荐
相关产品推荐

