1. __getattribute__
在访问实例属性时会最先调用__getattribute__方法,
例如:
class F(object):
def __init__(self):
self.name = 'A'
def hello(self):
print('hello')
def __getattribute__(self, item):
print('获取属性,方法', item)
return object.__getattribute__(self, item)
def next(self):
print("next")
a = F()
print(a.name)
a.hello()
a.next()
获取属性,方法 name
A
获取属性,方法 hello
hello
获取属性,方法 next
next
若调用没有的方法test(),则会抛出异常.
获取属性,方法 test
Traceback (most recent call last):
File "D:/spider_project/dianping/test.py", line 18, in <module>
a.test()
File "D:/spider_project/dianping/test.py", line 11, in __getattribute__
return object.__getattribute__(self, item)
AttributeError: 'F' object has no attribute 'test'
如果要避免抛出没有方法的异常,可以设置__getattr__方法,调用一个默认的函数.
2.__getattr__
对没有定义的属性名和实例,会用属性名作为字符串调用这个方法
class F(object):
def __init__(self):
self.name = 'A'
def __getattr__(self, item):
if item == 'age':
return 40
else:
raise AttributeError('没有这个属性')
f = F()
print(f.age)
调用f.age,因为没有age这个属性 所以自动调用__getattr__方法,通过item判断这个属性是否等于age,是的话返回40,不是抛出异常.
3.__setattr__
拦截 属性的的赋值语句
class F(object):
def __setattr__(self, key, value):
self.__dict__[key] = value
a = F()
a.name = 'alex'
print(a.name)
设置属性
如何自定义私有属性:
class F(object): # 基类--定义私有属性
def __setattr__(self, key, value):
if key in self.privs:
raise AttributeError('该属性不能改变')
else:
self.__dict__[key] = value
重新设置在privs列表中的属性,则会抛出异常,
class F1(F):
privs = ['age','name'] # 私有属性列表
x = F1()
x.name = 'egon' # AttributeError: 该属性不能改变
x.sex = 'male'
name在privs列表中会报错,sex不在则不会.
class F2(F):
privs = ['sex'] # 私有属性列表
def __init__(self):
self.__dict__['name'] = 'alex'
y = F2()
y.name = 'eva'