2013-06-18 24 views
1

我目前正在寫某種微型API來支持擴展模塊類。用戶應該能夠在配置中編寫他們的類名,並在我們的程序中使用它。合同是這個類的模塊有一個叫做create(**kwargs)的函數來返回我們的基本模塊類的一個實例,並且放在一個特殊的文件夾中。但是,一旦導入動態生成,isinstance檢查就會失敗。蟒蛇2.7 isinstance在動態導入模塊類失敗

模塊被放置在LIB /服務/ 名稱

模塊基類(在LIB /服務/服務)

class Service: 
    def __init__(self, **kwargs): 
     #some initialization 

示例模塊類(在LIB /服務/平)

class PingService(Service): 
    def __init__(self, **kwargs): 
     Service.__init__(self,**kwargs) 
     # uninteresting init 

def create(kwargs): 
    return PingService(**kwargs) 

導入功能

import sys 
from lib.services.service import Service 

def doimport(clazz, modPart, kw, class_check): 
    path = "lib/" + modPart 
    sys.path.append(path) 
    mod = __import__(clazz) 
    item = mod.create(kw) 

    if class_check(item): 
     print "im happy" 
     return item 

調用代碼

class_check = lambda service: isinstance(service, Service) 
s = doimport("ping", "services", {},class_check) 

print s 

from lib.services.ping import create 

pingService = create({}) 
if isinstance(pingService, Service): 
    print "why this?" 

到底是什麼,我做錯了

這裏是一個小例子拉上,只是提取和不帶參數運行test.py zip example

+1

首先,如果你正在使用Python 2 .x,你不應該使用舊式的類。總是做'class Service(object):',而不是'class Service:'。舊式課程的規則與新式課程明顯不同,並且你不想同時學習。 – abarnert

+1

其次,你的代碼根本不運行。例如,'mod.create(clazzItem)'只會在'clazzItem'上引發一個'NameError'。請給我們一個實際精簡的,可運行的例子。 – abarnert

+0

第一:這與我的問題無關,因爲我都嘗試過。第二:我喜歡舊式課程的規則:) –

回答

2

的問題是在你的ping.py文件。我不知道究竟是什麼原因,但是當它導入時不接受from service import Service這一行,所以你只需要將它改爲相對路徑:from lib.services.service import Service。添加lib/servicessys.path不能使它工作的繼承,這是我發現了奇怪的......

而且,我使用imp.load_source這似乎更穩健:

import os, imp 
def doimport(clazz, modPart, kw, class_check): 
    path = os.path.join('lib', modPart, clazz + '.py') 
    mod = imp.load_source(clazz, path) 
    item = mod.create(kw) 

    if class_check(item): 
     print "im happy" 
     return item 
+1

imp.load_source需要完全2個參數,1給出.. –

+0

謝謝...我更新了答案... –

+0

語法錯誤,主要錯誤存在。 PLZ看看我的示例 –