Python3:在非包中尝试相对导入

时间:2013-12-14 10:49:11

标签: python python-3.x importerror

我很抱歉这个基本问题,因为它与此类似: Stumped by relative imports

但我正在尝试遵循PEP328 http://www.python.org/dev/peps/pep-0328/#guido-s-decision 它对我不起作用:(

这些是我的文件:

dev@desktop:~/Desktop/test$ ls
controller.py  __init__.py  test.py

2to3表示一切正确:

dev@desktop:~/Desktop/test$ 2to3 .
RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
RefactoringTool: No files need to be modified.

文件内容:

dev@desktop:~/Desktop/test$ cat controller.py 
class Controller:
    def __init__(self):
        pass

dev@desktop:~/Desktop/test$ cat __init__.py 
# -*- coding: utf-8 -*-

dev@desktop:~/Desktop/test$ cat test.py 
#!/usr/bin/env python
from .controller import Controller 
if __name__ == '__main__':
    print('running...')

但导入它不起作用:

dev@desktop:~/Desktop/test$ python3 test.py 
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    from .controller import Controller 
ValueError: Attempted relative import in non-package
dev@desktop:~/Desktop/test$ 

任何帮助表示赞赏!提前谢谢!

2 个答案:

答案 0 :(得分:3)

您无法在包中使用脚本;您正在运行test不是 test.test。因此,顶级脚本不能使用相对导入。

如果您想将程序包作为脚本运行,则需要将test/test.py移至testpackage/__main__.py,将shell中的一个目录移至~/Desktop并告诉python运行包含python -m testpackage的包。

演示:

$ ls testpackage/
__init__.py   __main__.py   __pycache__   controller.py
$ cat testpackage/controller.py 
class Controller:
    def __init__(self):
        pass

$ cat testpackage/__init__.py 
# -*- coding: utf-8 -*-

$ cat testpackage/__main__.py 
from .controller import Controller
if __name__ == '__main__':
    print('running...')

$ python3.3 -m testpackage
running...

您无法命名包test; Python已经为测试套件提供了这样的包,并且可以在找到当前工作目录中的包之前找到它。

另一种方法是在软件包的之外创建一个脚本,然后从脚本中导入软件包。

答案 1 :(得分:0)

这不是主题,但是为了测试您的代码,我建议您查看本文Testing your code以及Test and python package structure

的主题