經過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
相關文章
相關標籤/搜索