2015-12-30 85 views
1

我意识到在StackOverflow已经有很多关于这个的问题,但我发现解决方案完全不清楚,并且经常相互矛盾。Python3在包内的相对导入

我有以下情形:我正在写一个Python(Python的3.4)封装结构如下:

mypackage/ 
    __init__.py (empty file) 
    mydir1/ 
     __init__.py (empty file) 
     mymodule1.py 
    mydir2/ 
     __init__.py (empty file) 
     mymodule21.py 
     mymodule22.py 
    mydir3/ 
     __init__.py (empty file) 
     mymodule31.py 
     mymodule32.py 
    tests/ 
     __init__.py (empty file) 
     test_something_in_mydir1.py 
     test_something_in_mydir2.py 
     test_something_in_mydir3.py 

我想tests/目录中的文件包含在包装内的一切的单元测试。问题是,不管哪一种方法我试试,我得到这个错误:

SystemError: Parent module '' not loaded, cannot perform relative import

我要指出,我想这个工作“开箱即用”,这意味着我不希望导入的东西使用他们的绝对路径,我不想改变我的路径变量。这些解决方案似乎都不是什么pythonic,它让我慢慢地爬上了墙。是否真的没有办法做到这一点?

我已经尝试了一堆东西已经包括下面的例子,但他们似乎都产生相同的结果:

from ..mydir1.mymodule1 import * 
from .mypackage.mydir1.mymodule1 import * 
from ...mypackage.mydir1.mymodule1 import * 

我累了,在每个__init__.py文件覆盖__all__变量以及进口如下所示:https://docs.python.org/3/reference/import.html#submodules

任何人都可以告诉我如何在文件test_something_in_mydir1.py中构造导入(例如),以便有权访问所有找到的类/函数用于单元测试包的mymodule1.py?

回答

1

如果test_something_in_mydir1.py包含:

import unittest 
from ..mydir1 import mymodule1 

class Test1(unittest.TestCase): 
    def test1(self): 
     self.assertEqual(mymodule1.x,1) # mymodule1 trivially contains x=1 

而且,如果单元测试从使用下面的命令含有的包(在此情况下,C:\Test)目录推出:

py -m unittest discover -v 

的测试被发现并且在相对进口下正确运行:

C:\Test>tree /f 
Folder PATH listing 
Volume serial number is CE8B-D448 
C:. 
└───mypackage 
    │ __init__.py 
    │ 
    ├───mydir1 
    │  mymodule1.py 
    │  __init__.py 
    │ 
    ├───mydir2 
    │  mymodule21.py 
    │  mymodule22.py 
    │  __init__.py 
    │ 
    ├───mydir3 
    │  mymodule31.py 
    │  mymodule32.py 
    │  __init__.py 
    │ 
    └───tests 
      test_something_in_mydir1.py 
      __init__.py 


C:\Test>py -m unittest discover -v 
test1 (mypackage.tests.test_something_in_mydir1.Test1) ... ok 

---------------------------------------------------------------------- 
Ran 1 test in 0.000s 

OK 
+0

没关系,我有一个命名错误,所以现在它发现了测试并尝试运行它,但尽管使用了相对导入'from ..mydir1.mymodule1 import *'它仍然给我错误SystemError:父模块''没有加载,不能执行相对导入' – RedHack

+0

我也试过'从..mydir1导入mymodule1',那也没有工作,产生相同的错误。 – RedHack

+0

我确信在我的具体情况下它不是什么愚蠢的东西,甚至重新创建了与我在这里使用的占位符相同的标题的目录,并确实发生了同样的问题。我创建了一个pastebin,以防万一它能帮助我查看我使用的精确命令以及我得到的错误(http://pastebin.com/08mutDrY) – RedHack