好吧,我认为无论我做错了什么,它可能都是显而易见的,但我无法弄清楚。我已阅读并重新阅读有关软件包的教程部分,我唯一可以想到的是,这不起作用,因为我正在直接执行它。这是目录设置:
eulerproject/
__init__.py
euler1.py
euler2.py
...
eulern.py
tests/
__init__.py
testeulern.py
以下是testeuler12.py(我编写的第一个测试模块)的内容:
import unittest
from .. import euler12
class Euler12UnitTests(unittest.TestCase):
def testtriangle(self):
"""
Ensure that the triangle number generator returns the first 10
triangle numbers.
"""
self.seq = [1,3,6,10,15,21,28,36,45,55]
self.generator = euler12.trianglegenerator()
self.results = []
while len(self.results) != 10:
self.results.append(self.generator.next())
self.assertEqual(self.seq, self.results)
def testdivisors(self):
"""
Ensure that the divisors function can properly factor the number 28.
"""
self.number = 28
self.answer = [1,2,4,7,14,28]
self.assertEqual(self.answer, euler12.divisors(self.number))
if __name__ == '__main__':
unittest.main()
现在,当我从IDLE和目录中的命令行执行此操作时,出现以下错误:
Traceback (most recent call last):
File "C:\Documents and Settings\jbennet\My Documents\Python\eulerproject\tests\testeuler12.py", line 2, in <module>
from .. import euler12
ValueError: Attempted relative import in non-package
我认为问题在于,由于我直接运行它,我无法进行相对导入(因为__name__
更改,而我对包描述的模糊理解是__name__
是其中的一部分它是如何告诉它在哪个包中的,但在那种情况下,你们建议如何导入从测试代码中存储1级的“生产”代码?
答案 0 :(得分:10)
我遇到了同样的问题。我现在使用nose来运行我的测试,并正确处理相对导入。
是的,这整个相对重要的东西令人困惑。
答案 1 :(得分:8)
通常你会在你的PYTHONPATH上有一个目录,其名称是你的包名。例如:
eulerproject/
euler/
__init__.py
euler1.py
...
tests/
...
setup.py
然后,您可以在系统范围内安装此系统,或确保在调用脚本时设置PYTHONPATH=/path/to/eulerproject/:$PYTHONPATH
。
这样的绝对导入将起作用:
from euler import euler1
修改:
根据Python文档,“用作Python应用程序主模块的模块应始终使用绝对导入。” (Cite)
因此,另一个答案提到的像nose
这样的测试工具可以正常工作,因为它导入的是包而不是从命令行运行它们。
如果您想手动执行操作,则可运行脚本需要位于包层次结构之外,如下所示:
eulerproject/
runtests.py
euler/
__init__.py
euler1.py
...
tests/
__init__.py
testeulern.py
现在,runtests.py
可以from euler.tests.testeulern import TestCase
而testeulern.py
可以from .. import euler1