Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,它们是面向对象的 Python 的一切。它们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了某一个魔法方法,那么这个方法就会在特殊的情况下自动被 Python 所调用。
功能
定义实例对象的属性被访问时的行为(不管该属性是否存在,另:通过类名访问属性不会调用该方法)
参数
self 表示对象本身,item 是一个字符串,表示属性名字
返回值
默认为 None,返回值会自动返回给触发它的对象,一般通过return super().getattribute(item) 返回 item 属性的值。
示例
class MyTest:
def __init__(self, age):
self.age = age
def __getattribute__(self, item):
return super().__getattribute__(item)
sample = MyTest(18)
print(sample.age)
class Tree(object):
def __init__(self, name):
self.name = name
self.cate = "plant"
def __getattribute__(self, obj):
print("哈哈")
return object.__getattribute__(self, obj)
aa = Tree("大树")
print(aa.name)
执行结果:
哈哈
大树
为什么会这个结果呢?
__getattribute__ 是属性访问拦截器,就是当这个类的属性被访问时,会自动调用类的__getattribute__ 方法。
在上面代码中,当调用实例对象 aa 的 name 属性时,不会直接打印,而是把 name 的值作为实参传进 __getattribute__ 方法中(参数 obj 可任意起名),经过一系列操作后,再把 name 的值返回。Python 中只要定义了继承 object 的类,就默认存在属性拦截器,只不过是拦截后没有进行任何操作,而是直接返回。
可以自己改写 __getattribute__ 方法来实现相关功能,比如查看权限、打印log日志等。如下代码:
class Tree(object):
def __init__(self, name):
self.name = name
self.cate = "plant"
def __getattribute__(self, *args, **kwargs):
if args[0] == "name":
print("log 大树")
return "this is 大树"
else:
return object.__getattribute__(self, *args, **kwargs)
aa = Tree("大树")
print(aa.name)
执行结果:
log 大树
this is 大树
plant