__getattribute__
属性拦截器,当访问对象属性时,会触发执行属性拦截器,常用于记录日志
class Person(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def __getattribute__(self, attr):
if attr == 'salary':
return "!!!Secret!!!"
else:
return object.__getattribute__(self, attr)
p1 = Person('Da', 1000)
p2 = Person('Yo', 2000)
print("Name: {} Salary: {}".format(p1.name, p1.salary))
执行效果
[root@bj-vmware-test1 tmp]# python35 attr.py
Name: Da Salary: !!!Secret!!!
思考下为什么掉方法也会触发属性拦截器?
class Person(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def __getattribute__(self, attr):
print('Get Attribute...')
if attr == 'salary':
return "!!!Secret!!!"
else:
return object.__getattribute__(self, attr)
def test(self):
return "test."
p1 = Person('Da', 1000)
print(p1.test())
输出
[root@bj-vmware-test1 tmp]# python35 attr_think.py
Get Attribute...
test.
对于对象来说,无论是方法还是"属性"对于它来说都是属性,只不过,一个指向了字符串(或者数字等),一个指向了的function,指向了function就被叫做方法,执行字符串被称之为属性
坑——递归调用
class Person(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def __getattribute__(self, attr):
if attr == 'salary':
return "!!!Secret!!!"
else:
return self.test
def test(self):
return "test."
p1 = Person('Da', 1000)
print(p1.name)
输出
File "attr_think.py", line 9, in __getattribute__
return self.test
File "attr_think.py", line 9, in __getattribute__
return self.test
File "attr_think.py", line 9, in __getattribute__
return self.test
File "attr_think.py", line 6, in __getattribute__
if attr == 'salary':
RecursionError: maximum recursion depth exceeded in comparison
所以,如果需要使用属性拦截器,小心递归调用的问题,如果需要调用同对象方法通过object.getattribute(self, attr)