__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__方法,然后分为两种情况:
- 不是对象中成员,就会报AttributeError错误;
- 是对象成员返回值;
__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__返回
结论:
- 先执行自己的__getattribute__
- 在执行父类的__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