When attr == '__str__', the function needs to return a callable object, because __str__ is expected to be a method. Simply returning a string will give you an error complaining that 'str' objects aren't callable.
However, the *args is not needed because __str__ is never called with any arguments. This suffices:
return lambda: '[Getattr str]'
Note that if you use python2 and inherit from object as is recommended, the example doesn't work. And if you use python3, it doesn't work either. This is the output in those cases:
getattr: __call__
None
<__main__.GetAttr object at 0xb728ff6c>
Why isn't __getattr__ invoked when attr == '__str__'?
It's because the base class object already implements a default __str__ method, and our __getattr__ function is only called for missing attributes. To fix the example as it is we must use the __getattribute__ method instead, but beware of the dangers.
class GetAttr(object):
def __getattribute__(self, attr):
print('getattr: ' + attr)
if attr == '__str__':
return lambda: '[Getattr str]'
else:
return lambda *args: None
A better and more readable solution would be to simply override the __str__ method explicitly.
class GetAttr(object):
def __getattr__(self, attr):
print('getattr: ' + attr)
return lambda *args: None
def __str__(self):
return '[Getattr str]'
But though it's better python, much of the point of the example is lost.