2014-09-13 53 views
0

我有這樣的項目結構:如何使用importlib在python中導入模塊?

腳本

-- A 
    == AA 
     ++ __init__.py 
     ++ AAA.py 
     ++ AAB.py 
     ++ AAC.py 
    == AB 
     ++ __init__.py 
     ++ ABA.py 
     ++ ABB.py 
     ++ ABC.py 
-- B 
    == BA 
     ++ __init__.py 
     ++ BAA.py 
     ++ BAB.py 
     ++ BAC.py 
    == BB 
     ++ __init__.py 
     ++ BBA.py 
     ++ BBB.py 
     ++ BBC.py 

我想導入內部Scripts/A/AA/AAA.py類爲Scripts/B/BB/BBC.py。我已經使用了一些解決方案:

  1. from AAA import *給我ImportError: No module named AAA
  2. from Scripts.A.AA.AAA import *給我ImportError: No module named Scripts.A.AA.AAA
  3. from ..A.AA.AAA import *給我ValueError: Attempted relative import beyond toplevel package
  4. from ....A.AA.AAA import *給我ValueError: Attempted relative import in non-package

我該怎麼辦?

編輯1:

我已經改變了項目的結構,現在是這樣的:

腳本

-- elements 
    == A 
     ++ __init__.py 
     ++ AAA.py 
     ++ AAB.py 
     ++ AAC.py 
    == B 
     ++ __init__.py 
     ++ BAA.py 
     ++ BAB.py 
     ++ BAC.py 
-- general 
    == imports.py 
    == __init__.py 
-- main.py 

我已經寫了這一段代碼進口所有類別:

elementDict = [] 
dirList = os.walk('elements') 
for dname in dirList: 
    fileList = dname[2] 
    for fname in fileList: 
     if fname != '__init__.py' and fname.endswith('.py') and (not fname.endswith('_ut.py')) and (not fname.endswith('~')): 
      path = dname[0].split(os.sep) 
      path = filter(None, path[path.index('elements'):]) 
      dir = '.'.join(path) 
      mod = importlib.import_module(dir + '.' + fname[:-3]) 
      for cname, obj in inspect.getmembers(mod, inspect.isclass): 
       if cname not in elementDict: 
        elementDict[cname] = obj 

這導致:

Traceback (most recent call last): 
    File "C:\Users\test\Scripts\general\imports.py", line 29, in __init__ 
    mod = importlib.import_module(dir + '.' + fname[:-3]) 
    File "C:\Python27\lib\importlib\__init__.py", line 37, in import_module 
    __import__(name) 
ImportError: No module named elements.A.AAA 

任何想法?

編輯2:

我已經解決了這個問題;我在elements中沒有任何__init__.py

回答

0

Relative imports只能在封裝結構內工作。有關更詳細的答案,請參見this question

在這種情況下,AABB是兩個不同的包,所以3和4中的相對導入失敗。 Scripts根本不是一個包(既不是AB),所以2失敗,因爲它不太可能,你在PYTHONPATH中有Scripts/A/AA也是1失敗。

您需要在您的PYTHONPATH中有Scripts/A,然後致電from AA.AAA import *。如果您在PYTHONPATH中已有Scripts,則可以添加一個Scripts/A/__init__.py文件以使目錄成爲python包,並調用from A.AA.AAA import *

+0

我檢查了'os.environ ['PYTHONPATH']'和'Scripts'在那裏;但是我從'A.AA.AAA import *'得到'沒有名爲A.AA.AAA'的模塊。 – 2014-09-13 09:19:15

+0

我剛纔看到,'A'根本就不是一個包。你是如何導入模塊「BB.BBC」的? – tynn 2014-09-13 09:56:18

+0

我沒有將它導入任何地方。 – 2014-09-13 10:55:15