Python中的__getattr__方法、__getattribute__方法及其应用

137 阅读1分钟

1.__getattr__方法

对象中有成员,不会触发,对象中没有成员时,会触发;

2__getattribute__方法

获取对象中的成员时,本质上会调用 __getattribute__方法,如果子类中没有定义该方法,则默认使用用父类中的方法; 如果获取的不是对象中的成员,就会报错;

3.相关示例代码如下:

class HttpRequest(object):
    def __init__(self):
        pass

    def v1(self):
        print("我是HttpRequest中的v1")

    def v2(self):
        print("我是HttpRequest中的v2")


class Request(object):
    def __init__(self, req, xx):
        self._request = req
        self.xx = xx

    def __getattr__(self, attr):
        try:
            return getattr(self._request, attr)
        except AttributeError:
            return self.__getattribute__(attr)

# ------------------------------------------------------
req = HttpRequest()
req.v1()    # 输出结果为:我是HttpRequest中的v1
req.v2()    # 输出结果为:我是HttpRequest中的v2

# ------------------------------------------------------
request = Request(req, 111)
print(request.xx)    # 输出结果为‘111’,request对象中有xx成员,`def __getattr__(self, attr):`

request.v1()
# 输出结果为:我是HttpRequest中的v1,request对象中没有v1,执行`def __getattr__(self, attr`):`,`self._request`(即req对象)中有v1,返回v1,如果req中也没有的成员,则会报错。
    
request.v2()    # 输出结果为:我是HttpRequest中的v2
request.v3()    # 报错

4.总结

通过关键的第17号至21行代码,将__getattr__方法与__getattribute__方法结合使用,可以将reqeust._request.v1()简写为reqeust.v1()