Joh*_*nal 52 python import module
我有以下目录:
mydirectory
??? __init__.py
??? file1.py
??? file2.py
Run Code Online (Sandbox Code Playgroud)
我有一个在file1.py中定义的函数f.
如果,在file2.py中,我这样做
from .file1 import f
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
SystemError:父模块''未加载,无法执行相对导入
为什么?以及如何使它工作?
Bak*_*riu 42
在包中启动模块作为可执行文件是一种不好的做法.
当您开发某些东西时,您要么构建一个库,该库旨在由其他程序导入,因此允许直接执行其子模块没有多大意义,或者您构建了一个可执行文件,在这种情况下没有理由让它成为一部分一揽子.
这就是setup.py您区分包和脚本的原因.site-packages当脚本将安装在/usr/bin(或类似的位置,具体取决于操作系统)下时,软件包将处于打开状态.
因此我建议使用以下布局:
/
??? mydirectory
| ??? __init__.py
| ??? file1.py
??? file2.py
Run Code Online (Sandbox Code Playgroud)
其中file2.py导入file1.py与任何其他想要使用该库的代码一样mydirectory,具有绝对导入:
from mydirectory.file1 import f
Run Code Online (Sandbox Code Playgroud)
当您setup.py为项目编写脚本时,您只需将其mydirectory列为包和file2.py脚本,一切都会正常工作.无需捣鼓sys.path.
如果由于某种原因,你真的想要实际运行一个包的子模块,那么正确的方法就是使用这个-m开关:
python -m mydirectory.file1
Run Code Online (Sandbox Code Playgroud)
这将加载整个包,然后将该模块作为脚本执行,从而允许相对导入成功.
我本人避免这样做.还因为很多人甚至不知道你可以做到这一点,并最终会得到与你相同的错误,并认为包破坏了.
关于当前接受的答案,该答案表示您应该使用隐式相对导入,from file1 import f因为它可以工作,因为它们位于同一目录中:
这是错的!
file1模块肯定会破坏(因为它将导入而不是你的模块!).即使它有效,file1也不会将其视为mydirectory包装的一部分.这可关系.
例如,如果file1使用pickle,则包的名称对于正确加载/卸载数据很重要.
mrK*_*ley 24
因为file1并且file2在同一目录中,您甚至不需要拥有__init__.py文件.如果你要扩大规模,那就把它放在那里.
要在同一目录中的文件中导入内容,只需这样做
from file1 import f
即,您不需要执行相对路径,.file1因为它们位于同一目录中.
如果您将运行整个应用程序的主要功能,脚本或其他内容位于另一个目录中,那么您将必须使所有内容相对于正在执行的任何位置.