[英]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.