Python __getattr__
1.__ getattr __
当我们访问一个不存在的属性的时候,会抛出异常,提示我们不存在这个属性。一般访问属性异常就是__getattr__方法抛出的。
例子:
class A(object):
def __init__(self, value):
self.value=value
def __getattr__(self, item):
print("into __getattr__")
return "can not find attr"
a = A(10)
print(a.value)
print(a.name)
"""
10
into __getattr__
can not find attr
"""
访问类里面存在的属性会正常返回值,但是如果访问一个不存在的属性最后会进入__getattr__()
在设计自己的类的时候,可以重写__getattr__()来实现一些提示功能
class Student(object):
def __getattr__(self, attr):
if attr in ('name', 'age', 'score'):
print (attr)
else:
raise AttributeError('Unkonw attribute : %s' % attr)
student = Student()
print(student.name)
print(student.age)
print(student.score)
print(student.id)
"""
name
None
age
None
score
None
AttributeError
AttributeError: Unkonw attribute : id
"""
class Student(object):
def __getattr__(self, attr):
def _func(*arg, **kwargs):
print( arg, kwarg)
if not attr.startswith('_'):
_func.func_name = attr
return _func
raise AttributeError('Unkonw attribute : %s' % attr)
student = Student()
print(student.name)
print(student._age)
"""
<function Student.__getattr__.<locals>._func at 0x7fbc305a2ca0>
AttributeError
<ipython-input-140-ed18ab9ef9e6> in __getattr__(self, attr)
7 _func.func_name = attr
8 return _func
----> 9 raise AttributeError('Unkonw attribute : %s' % attr)
10
11
AttributeError: Unkonw attribute : _age
"""
a = {'a':{'b':1}, 'b':2}
print(a['a'])
print(a['a']['b'])
print(a['b'])
"""
{'b': 1}
1
2
class Dict(dict):
def __init__(self, *args, **kwargs):
super(Dict, self).__init__(*args, **kwargs)
def __getattr__(self, name):
value = self[name]
if isinstance(value, dict):
value = Dict(value)
return value
obj = Dict(student={'age': 18}, name='ZhangSan')
print(obj)
print(obj.name)
print(obj.student)
print(obj.student.age)
"""
{'student': {'age': 18}, 'name': 'ZhangSan'}
ZhangSan
{'age': 18}
18
"""
2 __ setattr __
class A(object):
def __init__(self, value):
print( "into __init__")
self.value = value
def __setattr__(self, name, value):
print ("into __setattr__")
if value == 10:
print( "from __init__")
object.__setattr__(self, name, value)
a = A(10)
"""
into __init__
into __setattr__
from __init__
"""
print(a.value)
#10
a.value = 20
"""
into __setattr__
"""
print(a.value)
#20
注意避免死循环:
####死循环####
#在重写__setattr__和__delattr__方法的时候要尽量避免重复调用
class A(object):
def __init__(self, value):
self.value = value
def __setattr__(self, name, value):
self.name = value
### 避免死循环###
class A(object):
def __init__(self, value):
self.value = value
def __setattr__(self, name, value):
self.__dict__[name] = value
3. __ delattr __
a = A(20)
print(a.value)
del a.value
print(a.value)
"""
20
when can not find attribute into __getattr__
"""
参考博客1:https://blog.csdn.net/yusuiyu/article/details/87945149
参考博客2:https://www.jianshu.com/p/61c10a59fdab