一. 什么是python的反射机制?
1.反射
反射机制就是在运行时,动态的确定对象的类型,并可以通过字符串调用对象属性、方法、导入模块,是一种基于字符串的事件驱动。
python的反射机制,核心就是利用字符串去已存在的模块中找到指定的属性或方法,找到方法后自动执行,基于字符串的事件驱动!这也是python强大的自省能力!在Django的类视图 和API开发中,路由的底层dispatch方法就是利用反射机制实现的,现在就来看看它的实现原理。
解释型语言:程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次。因此效率比较低。相对于编译型语言存在的,源代码不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。比如Python/JavaScript / Perl /Shell等都是解释型语言。
python是一门解释型语言,因此对于反射机制支持很好。在python中支持反射机制的函数有getattr()、setattr()、delattr()、exec()、eval()、import,这些函数都可以执行字符串。具体函数的用法在这不详细解释
以下使用rest framework中的dispath举例,如何实现的反射
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
# 對原生的request進行加工
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
# 反射机制,通过getattr动态的获取self实例的 request.method.lower()属性
# request.method有'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'等方法,来动态获取给到handler
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
如果不用反射机制你可能的代码如下:
if request.method.lower() == get:
...
elif request.method.lower() == post:
...
...
相比较而言,反射实现的代码更简洁
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)