关于python:Python3:尝试在非包中进行相对导入

Python3: Attempted relative import in non-package

我很抱歉这个基本问题,因为它与此类似:
被相对进口困扰

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

这些是我的文件:

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

2to3表示一切正确:

1
2
3
4
5
6
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.

文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
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...')

但导入它不起作用:

1
2
3
4
5
6
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$

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


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

如果要将包作为脚本运行,则需要将test/test.py移动到testpackage/__main__.py,将shell中的一个目录移动到~/Desktop并告诉python运行带有python -m testpackage的包。

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ 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已经为测试套件提供了这样的包,并且可以在找到当前工作目录中的包之前找到它。

另一种方法是在包外部创建脚本并从脚本中导入包。


这不是真正的主题,但是为了测试你的代码我建议看一下这篇文章测试你的代码和这个主题的Test和python包结构