今天遇到一个使用反射机制的场景。

我要随机测试子模块中的任意一个函数,因为是随机测试,我无法事先确定我要导入哪些函数,不使用反射机制,有下面两种方法解决子模块函数导入问题。

方法一:使用"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)

参考资料:

results matching ""

    No results matching ""