经过config文件配置动态导入模块

需求:html

  固定的服务中要调用不一样的算法,当前服务中实现的动态导入是经过在config配置中加上参数:proto="AiProto(1,4)",在服务中from pathname import classname,而后经过a=eval(config.proto)的方式动态实例化。python

  这里面有个问题,就是开发期间的服务能够经过添加from pathname01 import classname01的方式将全部可能用到的类导入,而后服务启动只须要更改配置便可。可是在后期,还会不断地导入新的模块,那么每次不只须要修改config文件还须要在服务中添加from .. import ..的代码。算法

  那么如何实现仅须要修改config配置文件的动态导入呢?dom

 

解决思路:学习

  在config文件中经过元组的形式将参数传入,如:spa

proto = ('service.ai.ai_random','Ai_Random',7,1) # path,classname,arg1,arg2

 

在服务中,能够经过config.proto切片获取相应的参数:.net

pathname = config.proto[0]  # 'service.ai.ai_random'
modulename = config.proto[1]   # 'Ai_Random'
aid = config.proto[2]    # 7
pid = config.proto[3]    # 1

  咱们如今已经获取到了相应的参数,那么问题来了,咱们怎么导入呢?code

  一开始,我直接使用了下面的代码:htm

from pathname import modulename

  显而易见,因为pathname和modulename都是字符串,确定是不能成功的导入的。而后exec和eval都是执行字符串形式的指令的方法,并不能将字符串转换为变量。so,exec和eval也不可行。当前陷入了僵局,经常使用的简单方法已经不能知足我当前的需求。经过stackoverflow我发现了__import__方法,可是绝大多数都是实现了最简单的__import__('modulename')这样的动态导入,而不是我想要的这种。随机找了关于__import__各种资料,其中比较好理解且有助于学习的有:对象

  http://blog.csdn.net/xlisper/article/details/28722745

  http://python.jobbole.com/87492/

  https://www.cnblogs.com/xiaoyaowuming/p/5633207.html

  https://stackoverflow.com/questions/301134/dynamic-module-import-in-python

经过上面的这些资料,找到对应我应该使用的是:

  from pkg.module1 import submodule1

module1 = __import__('pkg.module1', fromlist=['submodule1'])  
module1.submodule1  
#当fromlist不为空时,__import__方法会返回name参数中最右面的模块对象,此处是module1。 

  参考上述示例个人代码就应该是:

  p = __import__(pathname,fromlist=[modulename,])

而后用p.modulename去调用类,发现我成功地导入了模块,可是不能加载类,怎么办呢?看到getattr方法,咱们来轻松解决:

try:
    p = __import__(pathname,fromlist=[modulename,])
    Proto = getattr(p,modulename)
except:
    pass
相关文章
相关标签/搜索