__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)

results matching ""

    No results matching ""