Relative import in Python 3 not working
我有以下目录:
1 2 3 4 | mydirectory ├── __init__.py ├── file1.py └── file2.py |
我在file1.py中定义了一个函数f。
如果,在file2.py中,我有
1 | from .file1 import f |
号
我得到以下错误:
SystemError: Parent module '' not loaded, cannot perform relative
import
号
为什么?如何使其发挥作用?
在包中作为可执行文件启动模块是一种糟糕的做法。
当您开发某个东西时,您要么构建一个库,该库是由其他程序导入的,因此直接执行其子模块没有多大意义,要么构建一个可执行文件,在这种情况下,没有理由使它成为包的一部分。
这就是为什么在
因此,我建议使用以下布局:
1 2 3 4 5 | / ├── mydirectory | ├── __init__.py | ├── file1.py └── file2.py |
如果
1 | from mydirectory.file1 import f |
。
当你为项目写一个
如果您出于某种原因确实想运行包的子模块,那么正确的方法是使用
1 | python -m mydirectory.file1 |
。
这将加载整个包,然后以脚本的形式执行模块,从而允许相对导入成功。
我个人会避免这样做。另外,因为很多人甚至不知道你能做到这一点,最终会得到和你相同的错误,并认为这个包是坏的。
关于目前接受的答案,它说您应该使用一个隐式的相对导入
这是错误的!
- 它在python3中不起作用,在python3中不允许隐式的相对导入,如果您碰巧安装了
file1 模块,它肯定会中断(因为它将被导入而不是您的模块!). 即使它起作用,
file1 也不会被视为mydirectory 包的一部分。这很重要。例如,如果
file1 使用pickle ,包的名称对于正确加载/卸载数据很重要。
由于
要在同一目录的文件中导入某些内容,请执行以下操作
埃多克斯1〔3〕
也就是说,您不需要执行相对路径
如果运行整个应用程序的主函数、脚本或其他内容在另一个目录中,那么您必须使所有内容都与正在执行的位置相关。
启动python源文件时,禁止使用相对导入来导入当前包中的另一个文件。
在文件中说:
请注意,相对导入基于当前模块的名称。由于主模块的名称始终是"uumain_uuuuuu",因此用作Python应用程序主模块的模块必须始终使用绝对导入。
所以,正如@mrkelley所说,在这种情况下,你需要使用绝对进口。
1 2 3 4 5 6 7 8 9 | myproject/ mypackage ├── __init__.py ├── file1.py ├── file2.py └── file3.py mymainscript.py |
从一个文件导入到另一个文件的示例
1 2 3 | #file1.py from myproject import file2 from myproject.file3 import MyClass |
号
将包示例导入到主脚本
1 2 | #mymainscript.py import mypackage |
https://docs.python.org/3/tutorial/modules.html包
https://docs.python.org/3/reference/import.html常规包
https://docs.python.org/3/reference/simple_stmts.html导入语句
https://docs.python.org/3/glossary.html term导入路径
变量sys.path是确定解释器对模块的搜索路径的字符串列表。它初始化为从环境变量pythonpath获取的默认路径,或者如果未设置pythonpath,则从内置默认路径获取。您可以使用标准列表操作修改它:
1 2 3 | import sys sys.path.append('/ufs/guido/lib/python') sys.path.insert(0, '/ufs/guido/myhaxxlib/python') |
。
在开头插入它有利于确保在命名冲突的情况下,在其他路径(甚至内置路径)之前搜索路径。