.
I think that the attributes of objects such as variables and methods defined in the class
statement are usually acquired by .
. For example, suppose you define the following class.
python
class Foo:
def __init__(self):
self.foo = "foo"
self.bar = "bar"
The attributes foo
and bar
of the instance foo
of Foo
can be obtained with .
.
python
>>> foo = Foo()
>>> foo.foo
'foo'
>>> foo.bar
'bar'
This .
behavior can be customized using the special attributes __getattr__
and __getattribute__
methods.
__getattr__
If you define __getattr__
, when you try to get an attribute in .
, the usual name search is done first, and if the specified attribute is still not found, __getattr__
is called and the returned value is used. Returns as that attribute.
The following class Foo
defines __getattr__
to always return the member variable foo
.
python
class Foo:
def __init__(self):
self.foo = "foo"
self.bar = "bar"
def __getattr__(self, name):
return self.foo
The instance foo
of Foo
has a member variable called self.bar
, so foo.bar
returns self.bar
, but there is no member variable called self.anything
. So self.__ getattr__ ("anything")
is executed and self.foo
(ie the string " foo "
) is returned.
python
>>> foo = Foo()
>>> foo.foo
'foo'
>>> foo.bar
'bar'
>>> foo.anything
'foo'
__getattribute__
If __getattribute__
is defined, this method will be called whenever you try to get an attribute in .
. In the definition of __getattribute__
, if you try to get the attribute of that object using .
, your own __getattribute__
will be called recursively, so to avoid that, the superclass ʻobject Use __getattribute__
of`.
python
class Bar:
def __init__(self):
self.foo = "foo"
self.bar = "bar"
def __getattribute__(self, name):
return object.__getattribute__(self, "foo")
As you can see from the following execution result, the instance bar
of Bar
has a member variable called self.bar
, but even if it is bar.bar
, it is __getattribute__
. self.foo(ie the string
" foo "`) is returned.
python
>>> bar = Bar()
>>> bar.foo
'foo'
>>> bar.bar
'foo'
>>> bar.anything
'foo'
getattr
and hasattr
The built-in functions getattr
and hasattr
are based on attribute acquisition customized with __getattr__
and __hasattr__
. So getting the attributes of an object with getattr
is the same as getting it with .
. If you check the instances of Foo
and Bar
in the above example, the output will be like this.
python
>>> getattr(foo, "bar")
'bar'
>>> getattr(bar, "bar")
'foo'
If __getattr__
or __getattribute__
returns a value no matter what attribute you specify (that is, ʻAttributeError does not occur),
hasattralways returns
True`.
python
>>> hasattr(foo, "anything")
True
>>> hasattr(bar, "anything")
True
Recommended Posts