https://qiita.com/ganariya/items/fb3f38c2f4a35d1ee2e8
In order to study Python, I copied a swarm intelligence library called acopy.
In acopy, many interesting Python grammars and idioms are used, and it is summarized that it is convenient among them.
This time, let's define a __getattr__
special method in the class.
As a way to retrieve attributes used inside an instance in Python
There is a way to refer to __dict__
.
The name of the namespace used inside the instance is defined as a dictionary in __dict __
.
For example, take the following example.
class A:
def __init__(self, x, y):
self.x = x
self.y = y
# {'x': 10, 'y': 20}
a = A(10, 20)
print(a.__dict__)
Instance a has names $ x, y $ You can retrieve them as a dictionary.
__getattr__
You can define a special method called __getattr__
in a Python class.
In a Python instance name call If called with an undefined name, it will return ** AttributeError **.
But if __getattr__
is defined,
Instead of returning an AttributeError "on a call with an undefined name", __getattr__
is executed.
Let's look at an example.
class A:
def __init__(self, x, y):
self.x = x
self.y = y
def __getattr__(self, name):
print(name, 'getattr')
if name == 'hello':
return self.world
raise AttributeError
def world(self, x):
return x
'''
{'x': 10, 'y': 20}
hello getattr
<bound method A.world of <__main__.A object at 0x10e602150>>
hello getattr
20
'''
a = A(10, 20)
print(a.__dict__)
print(a.hello)
print(a.hello(20))
The __getattr__
method is defined in the A class above.
When I try to call ʻa.hello, the attribute hello is not defined in a. So the
getattr` method is called and returns the world method instead.
In ʻa.hello (20)`, the world method is returned first, and the world method is given a value of 20 and executed. Therefore, it is executed when the name hello is confirmed.
Therefore, if you use the above properties, you will get the following useless code.
class A:
def __init__(self, x, y):
self.x = x
self.y = y
def __getattr__(self, name):
print(name, 'getattr')
if name == 'hello':
return self.world
if name == 'world':
return self.great
if name == 'great':
return self.bad
if name == 'bad':
return 0
raise AttributeError
'''
{'x': 10, 'y': 20}
hello getattr
world getattr
great getattr
bad getattr
0
'''
a = A(10, 20)
print(a.__dict__)
print(a.hello)
I can't think of many application examples, If there is no attribute, I think there is something like letting you do alternative rule processing. Also, it seems that the branch etc. may be changed depending on the call name.
class A:
def __getattr__(self, name):
self.nothing(name)
def exist(self):
print('exist!')
def nothing(self, name):
print(f'nothing {name}')
'''
exist!
nothing unnti
'''
a = A()
a.exist()
a.unnti
In addition, as each content as a separate article at a later date It seems that it can also be used by throwing an exception code when there is no name in the lambda expression.
-Python attribute handling mechanism
Recommended Posts