Search code examples
pythonpython-2.7new-style-class

New style class attribute search for builtin operations


Consider the following difference between classic classes and the new style classes.

   class A():
        data = 'abcd'
        def __getattr__(self, name): 
            return getattr(self.data, name)

    class B(object):
        data = 'abcd'
        def __getattr__(self, name): 
            return getattr(self.data, name)



    print(A()[0])       # Prints 'a'
    print(B()[0])       # TypeError: 'B' object does not support indexing

I do know that explanation for this property is that new style objects attribute search starts at class instead of instances for builtin operations. But the class object too has __getattr__ defined and why it doesn't get invoked for the missing attribute here which is __getitem__.


Solution

  • I figured out the answer is that the __getattr__ is called only if the attribute search starts at the instance object. But if the attribute search explicitly on the class and instance is skipped __getattr__ is never called.

    class B():
        data = 'abcd'
        def __getattr__(self, name):
            print('You are looking for something that doesn\'t exist')
            return None
    
    b = B()
    b.a
    You are looking for something that doesn't exist
    B.a
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: class B has no attribute 'a'
    

    Hence in classic classes the search for __getitem__ starts at instance object and __getattr__ is invoked whereas in the new style class the search starts at class object and hence __getattr__ is not invoked.