Python 反射

反射:本质是利用字符串的形式去对对象/模块进行操作其成员,一种基于字符串的时间驱动。
以我现在的理解,就是本来需要显示控制的函数现在以以一种输入的形式去调用。就是动态调用。再简单一点,就是由字符串反向去找变量,函数,类。
Python 里面主要有 4 个函数来集中控制:
getattr, hasattr delattr, setattr
反射经常用在 web 路由机制里面,根据 url 来找函数。

>>> import requests
>>> hasattr(requests, 'get')
True
>>> hasattr(requests, 'adgs')
False

>>> import redis
>>> getattr(redis, 'test', 'I love you')
'I love you'
# 当给定的对象有传入的字符串方法时,会返回 True,否则返回 False。getattr 获取字符串对应的对象,第三个参数表示没有此方法/对象时,执行给定的参数。
1
2

另外还有一种是根据模块的路径去导入对象:

module. cls_name = spider_cls_path.split('.', maxsplit=1)
import importlib
# 得到模块
m = importlib.import_modult(module_path)
# 得到具体的对象
cls = getattr(m, cks_name)
cls()

除了这个模块,内置函数 __import__ 也可以用于动态加载类和函数

# 默认情况下会打印 模块所在的位置
>>> __import__('random')
<module 'random' from 'C:\\Users\\xx\\Envs\\spider_\\lib\\random.py'>
>>> r = __import__('random')
>>> r.randint(0, 5)
4
>>> r.random()
0.2777376488265768
# 这种方式在层级目录导入时,需要添加一个额外的参数
# 假设在 item 目录下的 items.py 文件中有一个 b 变量
a = "test.items"
c = __import__(a, fromlist=True)
print(dd.b)

获取函数参数:

>>>def f(a, b ,c):
>>>    pass
>>> f.__code__.co_varnames      # 获取参数名称
3
>>>f.__code__.co_argcount      # 获取参数个数
('a', 'b', 'c')
# Python 3.6
>>> import insepct
>>> inspect.signature(f)
<Signature (a:int, b:int)>
# Python 2.7
>>> import inspect
>>> inspect.getargspec(f)
ArgSpec(args=['a'], varargs=None, keywords=None, defaults=None)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容