[英]Dynamically imported module doesn't think it has class
设置:Python 3.3
我正在创建一个应用程序,通过一个名为'sources'的文件夹查找.py文件,并查看它们以查找扩展我定义的名为'SourceBase'的类的类。 如果他们扩展SourceBase,我想创建一个新的类实例来处理。
我通过以下帖子做了一些相当多的研究,我在很大程度上理解这些:
我的文件夹设置是这样的,我相信是相关的:
EPDownloader [package]
\
epdownloader.py [main]
SourceBase.py [contains SourceBase class]
imageutils.py [this class will find and dynamically load the classes in the sources package]
sources [package]
\
source1.py [has class that extends SourceBase]
source2.py
...other plugins here...
我的问题是我正在使用以下代码(来自我上面列出的其他堆栈溢出问题)并且它正在我的模块中搜索类,但它找不到我的类。 它只是跳过它们。 我不确定是什么问题。 这是我执行搜索的代码(基于我发布的第一个链接):
<!--language: python-->
def getSources(self):
pluginbase=SourceBase.SourceBase
searchpath='sources'
#We want to iterate over all modules in the sources/ directory, allowing the user to make their own.
for root, dirs, files in os.walk('./'+searchpath):
print('files: ',files)
candidates = [fname for fname in files if fname.endswith('.py')
and not fname.startswith('__')]
classList=[]
if candidates:
for c in candidates:
modname = os.path.splitext(c)[0]
print('importing: ',modname)
module=__import__(searchpath+'.'+modname) #<-- You can get the module this way
print('Parsing module '+modname)
for cls in dir(module): #<-- Loop over all objects in the module's namespace
print('Inspecting item from module: '+str(cls))
cls=getattr(module,cls) #this seems to still be a module when it hits source1
print('Get attribute: '+str(cls))
if (inspect.isclass(cls)): # Make sure it is a class
print('...is a class')
if inspect.getmodule(cls)==module: # Make sure it was defined in module, not just imported
print('...is in a module')
if issubclass(cls,pluginbase): # Make sure it is a subclass of base
print('...subclasses '+pluginbase.__name__)
classList.append(cls)
print(classList)
这是它给我的相关输出(我修剪了这个代码输出的很多其他东西):
Inspecting item from module: source1
Get attribute: <module 'sources.source1' from '/Users/Mgamerz/Documents/workspace/code/EPDownloader/sources/source1.py'>
[] <--- signifies it failed to find the source class
我很确定我的子类化工作,这里是该类的片段:
from EPDownloader import SourceBase
class source1(SourceBase.SourceBase):
def __init__(self):
pass
我被这个问题困扰了。 我花了最后几个小时,我不知道该怎么做。 我有一种感觉,它是一个我没有看到的简单修复。 有人可以帮我找到这里的错误吗?
[注意:我查看了StackOverflow格式化帮助,并没有看到任何格式化'突出显示'的方法,即在文本上放置灰色背景但内联的方式。 这将有助于突出我试图传达的这个问题的部分内容。
请查看文档: http://docs.python.org/3.1/library/functions.html# 进口
当name变量的形式为package.module时,通常会返回顶级包(直到第一个点的名称),而不是按名称命名的模块 。 但是,当给出非空的fromlist参数时,将返回按名称命名的模块。
只需更换
module=__import__(searchpath+'.'+modname)
同
module=__import__(searchpath+'.'+modname, None, None, "*")
这是同为“从sources.source1进口*”告诉__import__
获取给定的模块内的一切。
你的__import__
:你不是导入一个模块,而是导入整个包(整个'sources'目录作为一个包)。
我可以修复你的代码:
for c in candidates:
modname = os.path.splitext(c)[0]
print('importing: ',modname)
# NEW CODE
sys.path.insert(0, searchpath)
module=__import__(modname) #<-- You can get the module this way
# END OF NEW CODE
print('Parsing module '+modname)
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.