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

Python2.7使用__getattr__触发TypeError: 'str'对象不可调用问题

问题原因与解决方案

这个问题的根源在于Python 2里旧式类(没有继承object的类)和新式类的属性查找机制差异,尤其是对特殊方法/属性的处理。

为什么MyInstance会报错?

你的MyClass是Python 2中的旧式类(没有继承object),而__getattr__在旧式类中的行为和新式类完全不同:

  • 对于旧式类,当你访问任何实例上不存在的属性(包括像__dir__、__repr__这类特殊方法)时,都会触发__getattr__。
  • 当你调用dir(MyInstance)时,Python会尝试访问实例的__dir__方法来获取属性列表。但旧式类实例本身没有__dir__方法,所以这个属性查找会失败,进而触发你的__getattr__,返回字符串'hello'。接下来dir()会尝试调用这个返回值(因为它期望__dir__是一个可调用方法),但字符串是不能被调用的,于是就抛出了TypeError: 'str' object is not callable。
  • 同样,当你直接输入MyInstance时,Python会尝试调用实例的__repr__方法来生成字符串表示。在旧式类的属性查找逻辑下,这个过程会触发__getattr__,返回的字符串会被当作方法去调用,同样导致报错。

而MyOtherClass虽然也是旧式类,但它没有定义__getattr__,所以当dir()或者打印实例时,Python会使用默认的逻辑(比如从类层面获取__repr__、用默认方式收集属性),所以行为符合预期。

解决方法

方法1:改用新式类(推荐)

把MyClass改成继承object的新式类,这样特殊方法的查找会直接在类层面进行,不会触发实例的__getattr__:

class MyClass(object):  # 继承object变为新式类
    def __init__(self, value):
        self.a = value
    def __getattr__(self, name):
        return 'hello'

修改后:

  • dir(MyInstance)会正常返回属性列表,使用从object继承的__dir__方法,不会触发你的__getattr__。
  • 直接输入MyInstance会返回类似<__main__.MyClass object at 0x0000000003458648>的正常表示。

方法2:在__getattr__中过滤特殊属性(兼容旧式类)

如果必须保留旧式类,可以在__getattr__中跳过对特殊属性的处理,让Python使用默认逻辑:

class MyClass:
    def __init__(self, value):
        self.a = value
    def __getattr__(self, name):
        # 跳过以双下划线包裹的特殊属性/方法
        if name.startswith('__') and name.endswith('__'):
            raise AttributeError(name)
        return 'hello'

这样,当访问__dir__、__repr__这类特殊属性时,会抛出AttributeError,Python会继续使用默认的处理逻辑,避免触发错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:50:46