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

为何已定义的属性值未正常输出?Python代码问题求助

问题分析:@property中访问父类属性输出None的原因

复现代码

class PageElement:
    def __init__(self, a, b):
        self.a = a
        self.x = b

    @property
    def prop(self):
        print(f"{self.x}")
        return 1

class Tag(PageElement):
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __getattr__(self, x):
        self.x = x
        print("Tag.getattr was invoked")

t = Tag(3, 4)
print(t.prop)

实际输出

Tag.getattr was invoked
None
1

核心原因拆解

问题出在__getattr__的返回规则和属性访问的执行顺序上:

  1. 实例无初始x属性:Tag的__init__没有调用父类的__init__,所以创建t后,实例仅包含a=3、b=4,不存在x属性。
  2. 访问t.prop触发属性查找:prop是父类的@property方法,执行其函数体时需要读取self.x。
  3. __getattr__被调用但无返回值:因为t没有x属性,Python会调用Tag的__getattr__('x')。你在方法里设置了self.x='x'并打印提示,但**__getattr__默认返回None(无return语句时)**。
  4. self.x的取值是__getattr__的返回值:Python中,当__getattr__处理属性访问时,属性的取值直接等于该方法的返回值。所以这次print(f"{self.x}")打印的是__getattr__返回的None——虽然你在方法里给t设置了x='x',但这个赋值不影响本次访问的结果。
  5. 后续实例才拥有x属性:执行完__getattr__后,t.__dict__里确实会出现x='x',但这是在本次self.x访问完成后才生效的,对之前的打印没有作用。

验证与修复

如果给__getattr__加上返回值,就能得到预期输出:

def __getattr__(self, x):
    self.x = x
    print("Tag.getattr was invoked")
    return self.x  # 添加返回值

此时输出变为:

Tag.getattr was invoked
x
1

另外,若希望Tag实例初始化时就继承父类的x属性,也可以在Tag的__init__中调用super().__init__(a, b),这样就不会触发__getattr__了。

内容的提问来源于stack exchange,提问作者Neo Anderson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:01:24