The application __getattr__,__setattr__,__get__,__set__,__getattribute__ in several classes are introduced first .
__getattr__: When attribute is not found in the class , __getattr__ is called and the custom code is executed. All the properties defined in the class are contained in __dict__, that is, __getattr__ is triggered if the corresponding property name is not found in the __dict__ .
classGet_try (Object):
def__init__(Self, value):
Self. value=value
def__getattr__ (self self< Span lang= "en-US" >.value=item
if __name__ = = "__main__" :
g=get_try ( ' value ' g.value1 #调用了 g.value1, Value1 incoming __getattr__ item. After calling __getattr, value=value1
print g.value
G.__dict_
E:\python2.7.11\python.exe e:/py_prj/fluent_python/chapter7.py
Value1
{' Value ': ' value1 '}
The g.value value is value1 When the result is printed
__GETATTRIBUTE__: Called unconditionally, __getattr__ is not called if __getattr__ is defined at the same time.
classGet_try (Object):
def__init__(Self, value):
Self.value=value
def __getattr__ (self self.value=item
def __getattribute__ ( Span lang= "en-US" >self print item
if Span lang= "en-us" >__name__ = = "__main__" :
g=get_try ( ' value ' )
g.value1
E:\python2.7.11\python.exe e:/py_prj/fluent_python/chapter7.py
Value1
The result is the same as before.
__setattr__ is called when it is necessary to define the property itself. For example Self.att=value will become self.__setattr__ ("att", value)get_try (): __init__(self, value):
Self. value=value
def__getattr__(Self, item):
Self. Value=item
def__getattribute__(Self, item):
Printitem
def __setattr__ (self self.__dict__[key]=value
Span lang= "en-US" >if __name__ = = "__main__" :
g=get_try ( ' value ' g.value1=3
print g.value1
print g.__dict__
E:\python2.7.11\python.exe e:/py_prj/python_cookbook/chapter8.py
3
{' value1 ': 3, ' value ': ' Value '}
It is important to note that the Self.key=value assignment cannot be performed at the time of __setattr__ , because this means that the self.__setattr__ is not kept in call . This creates an infinite recursive loop. Eventually causes a stack overflow exception. When we call, the error of the report is like this
File "e:/py_prj/python_cookbook/chapter8.py", line 107, in __setattr__
Self.key=value
File "e:/py_prj/python_cookbook/chapter8.py", line 107, in __setattr__
Self.key=value
Runtimeerror:maximum recursion depth exceeded
In fact, when we do not implement __setattr__, we also implicitly call this function when assigning a value to a property. So what are the benefits of this implementation? The advantage is that we can assign to which properties to assign values.
classGet_try ():
def__init__(Self, value):
Self. value=value
def__getattr__(Self, item):
Self. Value=item
def__getattribute__(Self, item):
PrintItem
def__setattr__(Self, key, value):
ifKey = =' value1 ':
print ' incorrect key '
else :
self. __dict__[Key]=value
if __name__ = = "__main__":
G=get_try (' value ')
g.value1=3
g.value2=4
Print G.__dict__
E:\python2.7.11\python.exe e:/py_prj/python_cookbook/chapter8.py
Incorrect key
{' value2 ': 4, ' value ': ' Value '}
In the above code, when assigning a value to a value1, it is first judged. If it is value1, print incorrect key. So it's a success to see when the value2 is assigned. In the same way, we can use __setattr__ to prevent subsequent assignments of properties that are already in the class:
classGet_try ():
def__init__(Self, value):
Self. value=value
def__getattr__(Self, item):
Self. Value=item
def__getattribute__(Self, item):
PrintItem
def__setattr__(Self, key, value):
offKeyinchSelf.__dict__:
Print ' already exist '
else :
self. __dict__[Key]=value
if __name__ = = "__main__":
G=get_try (' value ')
G.value=4
g.value1=3
Print G.__dict__
E:\python2.7.11\python.exe e:/py_prj/python_cookbook/chapter8.py
Already exist
{' value1 ': 3, ' value ': ' Value '}
The above code first determines whether the assigned object already exists and prints already if it exists exist
Python Cookbook Third Edition learning Note 12: Classes and Objects (iii) Create a new class or instance property