欢迎来到赛兔子家园

__getattribute__ 和 __getattr__方法

__getattribute__

获取对象中的成员时,本质上会调用先执行__getattribute__方法,默认我们不定义就用父类中的。

class Request:
    def __init__(self,request):
        self._request = request


    def __getattribute__(self, attr):
        print("执行__getattribute__",attr)
        return super().__getattribute__(attr)


obj = Request("Http")
# 获取obj对象中成员_request
print(obj._request)
# 输出结果
# 执行__getattribute__ _request
# Http

# 获取obj对象中没有成员
print(obj.name)
# 输出结果:
# 执行__getattribute__ name
# 然后报错:AttributeError: 'Request' object has no attribute 'name'

结论:获取对象中成员时先执行__getattribute__方法,然后分为两种情况:

  1. 不是对象中成员,就会报AttributeError错误;
  2. 是对象成员返回值;

__getattr__方法

获取对象中不存在成员时,执行__getattr__方法

class Request:
    def __init__(self,request):
        self._request = request

    def __getattr__(self, attr):
        print("执行__getattr__")

obj = Request("Http")
# 获取obj对象中不存在成员name,调用执行__getattr__方法
print(obj.name)

# 输出结果
执行__getattr__
None

结论:获取对象中不存在的成员时,执行__getattr__方法,在该方法中可以自定义return值,默认None;

__getattribute__ 和  __getattr__同时存在

class Request:
    def __init__(self,request):
        self._request = request


    def __getattribute__(self, attr):
        print("执行__getattribute__",attr)
        return super().__getattribute__(attr)

    def __getattr__(self, attr):
        print("执行__getattr__")
        return "__getattr__返回"


obj = Request("Http")
# 获取obj对象中成员_request
print(obj._request)
# 输出结果
# 执行__getattribute__ _request
# Http

# 获取obj对象中没有成员
print(obj.name)
# 输出结果:
# 执行__getattribute__ name
# 执行__getattr__
# __getattr__返回

结论:

  1. 先执行自己的__getattribute__
  2. 在执行父类的__getattribute__
  • 2.1 是自己对象,直接获取并返回
  • 2.2 不是自己对象,调用__getattr__

对象封装示例:

class HttpRequest:
    def __init__(self):
        self.GET = {}
        self.POST = {}
        self.COOKIES = {}
        self.META = {}
        self.FILES = {}

        self.path = ""
        self.path_info = ""
        self.method = None

    def body(self):
        return "body"

    def headers(self):
        return "headers"

    def get_host(self):
        return "get_host"

    def get_port(self):
        return "get_port"

    def is_ajax(self):
        return "is_ajax"

    def is_secure(self):
        return "is_secure"


class DrfRequest:
    def __init__(self, name, request):
        self.name = name
        self._request = request

    def query_params(self):
        return "drf_query_params"

    def data(self):
        return "drf_data"

    # request对象中不存在的成员时,会执行__getattr__(self,attr)方法,attr参数值是不存在成员名
    def __getattr__(self, attr):
        try:
            return getattr(self._request, attr)
        except AttributeError:
            return self.__getattribute__(attr)


http_request = HttpRequest()
print(http_request.get_host())

request = DrfRequest(name="赛兔子", request=http_request)

print(request.data())  # 执行request对象中data()方法
print(request.headers())  # 执行request对象中不存在成员headers()时,调用__getattr__方法

# 输出
# get_host
# drf_data
# headers

 

posted on 2024-03-07 09:45  赛兔子  阅读(3)  评论(0编辑  收藏  举报

导航