You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:45:30