What is the relationship between __getattr__ and getattr?
Alex's answer was good, but providing you with a sample code since you asked for it :)
class foo: def __init__(self): self.a = "a" def __getattr__(self, attribute): return "You asked for %s, but I'm giving you default" % attribute>>> bar = foo()>>> bar.a'a'>>> bar.b"You asked for b, but I'm giving you default">>> getattr(bar, "a")'a'>>> getattr(bar, "b")"You asked for b, but I'm giving you default"
So in short answer is
You use
__getattr__
to define how to handle attributes that are not found
and
getattr
to get the attributes
getattr
is a built-in function taking (at least) two arguments: the object from which you're getting the attribute, and the string name of the attribute.
If the string name is a constant, say 'foo'
, getattr(obj, 'foo')
is exactly the same thing as obj.foo
.
So, the main use case for the built-in function getattr
is when you don't have the attribute name as a constant, but rather as a variable. A second important use case is when you pass it three arguments, rather than just two: in that case, if the attribute is absent from the object, getattr
returns the third, "default", argument, rather than raising an exception.
__getattr__
is a special method, defined in a class, that gets invoked when some attribute of an instance of that class is requested, and other normal ways to supply that attribute (via the instance's __dict__
, slots, properties, and so on) all failed. You can define it, for example, when you want to delegate otherwise-undefined attribute lookups to other objects.
So your second example is wrong because the builtin getattr
can never be called with a single argument.
The third one fails because the dictionary you're trying to "get an attribute" from does not have that attribute -- it has items, which are totally disjoint from attributes of course.
__getattr__()
is a special method function that you can define. When a member lookup fails, this function will be called.
getattr()
is a function you can call to attempt a member lookup. If the lookup succeeds, you get the member (perhaps a method function object, or perhaps a data attribute object). getattr()
can also return a default in the case the lookup fails.
If you declare a __getattr__()
member function, you can make it succeed sometimes, or you can make it succeed every time.
class A(object): def __getattr__(self, name): return "I pretend I have an attribute called '%s'" % namea = A()print a.foo # prints "I pretend I have an attribute called 'foo'"
Python also has __getattribute__()
which is always called on every lookup. It is very dangerous because it can make it impossible to access members normally.
class A(object): def __init__(self, value): self.v = value def __getattribute__(self, name): return "I pretend I have an attribute called '%s'" % namea = A(42)print a.v # prints "I pretend I have an attribute called 'v'"print a.__dict__["v"] # prints "I pretend I have an attribute called '__dict__'"
Oops, it is now impossible to access a.v!