关于python:从包中的父目录导入模块

Import a module from the parent directory within packages

我已经提到了几个主题和文章,包括:

  • 从父文件夹导入模块
  • 无法从其他文件夹导入python
  • 从父目录导入脚本
  • PEP 328——进口:多行和绝对/相对

但不能达到预期的效果。

假设我有一个叫做"地狱世界"的目录:

1
2
3
4
5
6
helloworld
|--__init__.py
|--say_hello.py
|--another_hello
   |--__init__.py
   |--import_hello.py

这是说"你好,小家伙:

1
2
3
4
def hello_world():
    print("Hello World!")
if __name__ =="__main__":
    hello_world()

这是importu hello.py:

1
2
from .. import say_hello
say_hello.hello_world()

我希望在调用python /path/to/import_hello.py的任何位置导入say_hello模块,而不使用sys模块。

但是,现在当我做python /path/to/import_hello.py时,它会返回ValueError: attempted relative import beyond top-level package,我不知道它为什么不起作用。

即使这样也不行:

1
2
from helloworld import say_hello
say_hello.hello_world()

它会给我一个(5)。


您不能在这样的包中间运行脚本。当你这样做的时候,你不是运行基于/path/to/helloworldsparent/helloworld.another_hello.import_hello,而是运行基于/path/to/helloworldsparent/helloworld/another_hello__main__。所以,它没有一个作为..import的父包。

您可以使用-m运行模块:

1
$ python -m helloworld.another_hello.import_hello

…假设helloworld的目录在你的sys.path上(例如,因为你已经把它安装到site-packages中,或者因为你当前的工作目录是它的父目录,或者因为你已经设置了PYTHONPATH

但是一个更干净的解决方案通常是让深层模块单独存在,并在顶层编写"入口点"脚本,如下所示:

1
2
import helloworld.another_hello.import_hello
helloworld.another_hello.import_hello.main()

如果您使用的是setuptools(而且您确实需要足够复杂的软件包,需要两个级别),您可以让它在安装时(或在开发期间,在--inplace时)自动创建入口点脚本。请参阅文档中的自动脚本创建(但您可能还需要阅读其他部分来获得完整的想法;文档非常大和复杂)。


我觉得您可以先尝试将父路径添加到系统路径,然后尝试使用导入。

1
2
3
4
from sys import path as pylib
import os
pylib += os.path.abspath('..')
from helloworld import say_hello

希望有帮助!!