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)。
- 错误很明显。顶级包没有父级。
- @代码学徒,我以为我在指定import hello.py所在的父文件夹。在这种情况下,父文件夹应该是helloworld文件夹,不是吗?
- 可能复制了python子模块导入疯狂
您不能在这样的包中间运行脚本。当你这样做的时候,你不是运行基于/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时)自动创建入口点脚本。请参阅文档中的自动脚本创建(但您可能还需要阅读其他部分来获得完整的想法;文档非常大和复杂)。
- 谢谢。但我不太清楚在使用setuptools时,"让深层模块单独使用"是什么。这是否意味着我可以像现在这样离开import hello.py,即from .. import say_hello; say_hello.hello_world()?
- @Ytu-from … import行可以工作,但是您通常希望将顶级代码(say_hello.hello_world())移动到某个函数中,该函数可以在某人执行import helloworld.another_hello.import_hello之后被调用,而不是让它在某个进程中第一次执行import时运行。换句话说,您需要的是包中的模块,而不是脚本。
- 谢谢你的帮助。然而,我一直未能在import_hello中导入模块,也未能通过在安装入口点使用控制台脚本创建的命令来获取ModuleNotFoundError。
我觉得您可以先尝试将父路径添加到系统路径,然后尝试使用导入。
1 2 3 4
| from sys import path as pylib
import os
pylib += os.path.abspath('..')
from helloworld import say_hello |
希望有帮助!!