今天遇到一个使用反射机制的场景。
我要随机测试子模块中的任意一个函数,因为是随机测试,我无法事先确定我要导入哪些函数,不使用反射机制,有下面两种方法解决子模块函数导入问题。
方法一:使用"from 子模块名 import *"这种方式,事先将所有待测试函数都导入进来
方法二:测试函数A之前导入A,测试B之前导入B,测试函数C之前导入C
这两种方法明显有弊端,方法一显得很累赘,可能我只需要测一个函数,比如函数A,但你把其它不需要用到的函数全导入进了内存。方法二显得不灵活,每次测试前都要进行导入,可以是可以,这也不出错,但作为一个有追求的程序员,你能接受这么干吗?必须不答应。
好了,不多说废话,直接上代码。
def reflect_x(*args, **kwargs):
"""
reflect_x:使用反射机制定义调用函数。
根据输入字符串,在指定模块里查找对应函数,执行函数,返回结果
Parameters
----------
args:第一个必须是函数名,后面才是函数调用参数(必输)
kwargs:函数调用参数(关键字参数,可选)
Return
------
DataFrame,返回对应的df
"""
f_name = args[0]
print "f_name:",type(f_name),f_name
# 如果不设置fromlist参数,只会在"get.get"包里面__init__中查找。
f_folder = __import__("get.get", fromlist = True)
print "f_folder:",type(f_folder),f_folder
f_func = getattr(f_folder, f_name, None)
print "f_func:",type(f_func),f_func
if f_func:
# 实际执行时,只能从args第二个参数开始传入
df = f_func(*args[1:], **kwargs)
return df
else:
print "f_func not found"
reflect_x就是利用反射机制定义的函数,每次传入一个函数名,就导入对应的函数,有效解决了上面方法一和方法二的弊端。
在主程序中,这样调用就行了。
if __name__ == '__main__':
# 测试print_msg新增*args可变参数是否正确
# reflect_x第一个参数必须传入待测试的函数名,后面是待测试函数的参数
df = reflect_x('fund_holdings',2017,03)
print "df head(1):\n",df.head(1)
参考资料: