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

Python类中同时存在__getattribute__和__getattr__时,为何会出现意外的shape属性?

为什么你的实例里突然多了个shape属性?

嘿,这个问题其实和你的代码逻辑本身关系不大,罪魁祸首是PyCharm的调试器!让我给你拆解一下整个过程:

首先,先回忆你写的__getattr__方法的特性:当你访问一个实例上不存在的属性时,Python会自动调用这个方法。而你的__getattr__逻辑更“激进”——只要碰到不存在的属性,就直接用__setattr__把这个属性加到实例上,值设为'fred'。

那shape是哪来的?PyCharm的调试器在展示实例详情的时候,会偷偷尝试访问一些常见属性(比如shape,这个属性在numpy数组、PyTorch张量这类数据结构里很常见),用来判断实例的类型或者补充显示信息。当调试器访问x.shape时,这个属性原本根本不存在于你的X实例里,所以直接触发了你写的__getattr__方法,于是shape就被自动添加到了实例上,值就是你设置的'fred'。

你可以做个小实验验证这个结论:

  • 不要用调试模式,直接运行代码然后打印dir(x),你会发现只有count属性,完全看不到shape;
  • 或者在__getattr__里加一行打印日志:
    def __getattr__(self, item):
        print(f"触发__getattr__:访问属性{item}")
        return self.__setattr__(item, 'fred')
    
    启动调试后,你会在控制台看到调试器触发了对shape的访问记录。

另外提个小建议:你的__getattr__实现会给所有不存在的属性自动赋值,这在调试场景很容易被工具触发产生意外属性。如果你的需求只是处理特定属性,最好加个判断,比如:

def __getattr__(self, item):
    if item == 'target_attr':
        value = 'fred'
        self.__setattr__(item, value)
        return value
    # 其他属性抛出正常的AttributeError,避免干扰调试工具
    raise AttributeError(f"'X' object has no attribute '{item}'")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:29:08