簡體   English   中英

動態導入的模塊不認為它有類

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM