2014-09-13 52 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