2024-05-07 07:31:14 发布
网友
我有以下目录:
mydirectory ├── __init__.py ├── file1.py └── file2.py
我在file1.py中定义了一个函数f。
如果,在file2.py中,我是
from .file1 import f
我得到以下错误:
SystemError: Parent module '' not loaded, cannot perform relative import
为什么?如何让它发挥作用?
在包中以可执行文件的形式启动模块是一种不好的做法。
当你开发某个东西时,你要么构建一个库,这个库将被其他程序导入,因此允许直接执行它的子模块没有多大意义,要么构建一个可执行文件,在这种情况下,没有理由让它成为包的一部分。
这就是在setup.py中区分包和脚本的原因。程序包将位于site-packages下,而脚本将安装在/usr/bin(或类似的位置,具体取决于操作系统)。
setup.py
site-packages
/usr/bin
因此,我建议使用以下布局:
/ ├── mydirectory | ├── __init__.py | ├── file1.py └── file2.py
其中,file2.py将file1.py作为任何其他希望使用库的代码导入,mydirectory,并使用绝对导入:
file2.py
file1.py
mydirectory
from mydirectory.file1 import f
当您为项目编写setup.py脚本时,您只需将mydirectory作为包和file2.py作为脚本列出,一切都将正常工作。不需要摆弄sys.path。
sys.path
如果出于某种原因,您确实希望运行包的子模块,那么正确的方法是使用-m开关:
-m
python -m mydirectory.file1
这将加载整个包,然后将模块作为脚本执行,从而允许相对导入成功。
我个人不会这么做。也因为很多人甚至不知道你能做到这一点,最终会得到与你相同的错误,并认为包是坏的。
关于当前接受的答案,它说您应该只使用一个隐式相对导入from file1 import f,因为它将工作,因为它们在同一目录中:
from file1 import f
这是错误的!
file1
即使它起作用,file1也不会被视为mydirectory包的一部分。这个可以物质。
例如,如果file1使用pickle,则包的名称对于正确加载/卸载数据非常重要。
pickle
在启动python源文件时,禁止使用相对导入来导入另一个文件(即当前包中的文件)。
在documentation中说:
注意,相对导入基于当前模块的名称。由于主模块的名称始终为“\uu main\uu”,因此用作Python应用程序主模块的模块必须始终使用绝对导入。
所以,正如@mrKelley所说,在这种情况下需要使用绝对导入。
由于file1和file2位于同一目录中,您甚至不需要有__init__.py文件。如果你想扩大规模,那就把它留在那里。
file2
__init__.py
要在同一目录的文件中导入某些内容,请执行以下操作
也就是说,不需要执行相对路径.file1,因为它们在同一个目录中。
.file1
如果运行整个应用程序的主函数、脚本或其他东西位于另一个目录中,则必须使所有内容都与正在执行的位置相关。
在包中以可执行文件的形式启动模块是一种不好的做法。
当你开发某个东西时,你要么构建一个库,这个库将被其他程序导入,因此允许直接执行它的子模块没有多大意义,要么构建一个可执行文件,在这种情况下,没有理由让它成为包的一部分。
这就是在
setup.py
中区分包和脚本的原因。程序包将位于site-packages
下,而脚本将安装在/usr/bin
(或类似的位置,具体取决于操作系统)。因此,我建议使用以下布局:
其中,
file2.py
将file1.py
作为任何其他希望使用库的代码导入,mydirectory
,并使用绝对导入:当您为项目编写
setup.py
脚本时,您只需将mydirectory
作为包和file2.py
作为脚本列出,一切都将正常工作。不需要摆弄sys.path
。如果出于某种原因,您确实希望运行包的子模块,那么正确的方法是使用
-m
开关:这将加载整个包,然后将模块作为脚本执行,从而允许相对导入成功。
我个人不会这么做。也因为很多人甚至不知道你能做到这一点,最终会得到与你相同的错误,并认为包是坏的。
关于当前接受的答案,它说您应该只使用一个隐式相对导入
from file1 import f
,因为它将工作,因为它们在同一目录中:这是错误的!
file1
模块(因为它将被导入而不是您的模块!),它肯定会崩溃。即使它起作用,
file1
也不会被视为mydirectory
包的一部分。这个可以物质。例如,如果
file1
使用pickle
,则包的名称对于正确加载/卸载数据非常重要。在启动python源文件时,禁止使用相对导入来导入另一个文件(即当前包中的文件)。
在documentation中说:
注意,相对导入基于当前模块的名称。由于主模块的名称始终为“\uu main\uu”,因此用作Python应用程序主模块的模块必须始终使用绝对导入。
所以,正如@mrKelley所说,在这种情况下需要使用绝对导入。
由于
file1
和file2
位于同一目录中,您甚至不需要有__init__.py
文件。如果你想扩大规模,那就把它留在那里。要在同一目录的文件中导入某些内容,请执行以下操作
from file1 import f
也就是说,不需要执行相对路径
.file1
,因为它们在同一个目录中。如果运行整个应用程序的主函数、脚本或其他东西位于另一个目录中,则必须使所有内容都与正在执行的位置相关。
相关问题 更多 >
编程相关推荐