需求: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