我试图在Python 2.7中定义一个简单的类和实例,但是我遇到了__getattr__的麻烦。以下是最小的工作示例:
class MyClass:
def __init__(self,value):
self.a = value
def __getattr__(self,name):
return 'hello'
class MyOtherClass:
def __init__(self,value):
self.a = value
MyInstance = MyClass(6)
MyOtherInstance = MyOtherClass(6)
现在,如果我输入dir(MyInstance)
,则会得到:
TypeError: 'str' object is not callable
但是,如果我输入dir(MyOtherInstance)
,则会得到:
['__doc__', '__init__', '__module__', 'a']
如果我输入MyInstance
,则会得到:
TypeError: 'str' object is not callable
但是,如果我输入MyOtherInstance
,则会得到:
<__main__.MyOtherClass instance at 0x0000000003458648>
我期望MyOtherInstance
的行为。为什么我的MyInstance
不会出现这种情况?
答案 0 :(得分:3)
问题在于MyClass
是旧式类(即,它没有显式继承自object
或另一个新样式类),这意味着__getattr__
正在用于魔术方法,这些方法不会触发新类中对__getattr__
的调用。
要查看此内容,请将您的班级更改为
class MyClass:
def __init__(self,value):
self.a = value
def __getattr__(self,name):
print("Looking up %s" % (name,))
return 'hello'
仅使用MyInstance
会触发对MyInstance.__repr__
的调用,但是__repr__
的计算结果是字符串'hello'
,而不是类的__repr__
方法。
>>> MyInstance
Looking up __repr__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
类似地,dir(MyInstance)
触发对MyClass.__dir__
的调用,而__dir__
同样是字符串'hello'
,而不是适当的方法。
>>> dir(MyInstance)
Looking up __dir__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
MyOtherClass
并没有相同的问题,因为您没有覆盖__getattr__
。
从object
继承可以解决问题;在退回到__getattr__
之前,先分别查找魔术方法。
class MyClass(object):