Python魔法方法(11):__getattribute __(self, item) 方法

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

猜你喜欢

转载自blog.csdn.net/youzhouliu/article/details/125425034