2013-06-18 57 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看看我的示例 –