Python – Using __getattr__ causes TypeError : ‘str’ object is not callable – Python 2. 7

Using __getattr__ causes TypeError : ‘str’ object is not callable – Python 2. 7… here is a solution to the problem.

Using __getattr__ causes TypeError : ‘str’ object is not callable – Python 2. 7

I

tried to define a simple class and instance in Python 2.7, but I’m having trouble with __getattr__. The following minimal working example:

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)

Now, if I type dir(MyInstance), I get:

TypeError: 'str' object is not callable

But if I type dir(MyOtherInstance) I get:

['__doc__', '__init__', '__module__', 'a']

Similarly, if I type MyInstance, I get:

TypeError: 'str' object is not callable

But if I type MyOtherInstance I get:

<__main__. MyOtherClass instance at 0x0000000003458648>

MyOtherInstance behaved as I expected. Why don’t I get this behavior when I use MyInstance?

Solution

The problem is that MyClass is a legacy class (i.e., it doesn’t explicitly inherit from object or another modern class), which means that __getattr__ is used for magic methods and does not trigger a call to __getattr__ in a modern class.

To see this, change your class to

class MyClass:
    def __init__(self,value):
        self.a = value

def __getattr__(self,name):
        print("Looking up %s" % (name,))
        return 'hello'

The simple use of MyInstance triggers a call to MyInstance.__repr__, but __repr__ evaluates to the string ‘hello’ instead of the class's __repr__ method.

>>> MyInstance
Looking up __repr__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable

Similarly, dir(MyInstance) triggers a call to MyClass.__dir__, while __dir__, which is also the string ‘hello', is not an appropriate method.

>>> dir(MyInstance)
Looking up __dir__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable

MyOtherClass doesn’t have the same problem because you don’t overwrite __getattr__.

Inheriting from object solves this problem; Look for magic methods individually before going back to __getattr__.

class MyClass(object):

Related Problems and Solutions