Import Script from a Parent Directory
如何导入驻留在父目录中的模块(python文件)?
两个目录中都有一个__init__.py文件,但我仍然无法从父目录导入文件?
在此文件夹布局中,脚本B正在尝试导入脚本A:
1 2 3 4 5 6
| Folder A:
__init__.py
Script A:
Folder B:
__init__.py
Script B(attempting to import Script A) |
脚本B中的以下代码不起作用:
1
| import ../scriptA.py # I get a compile error saying the"." is invalid |
-
不完全回答您的问题,但如果您在文件夹A中运行init.py并尝试导入文件夹B或脚本B,脚本A将成功导入脚本B中。
您不导入导入模块的Python脚本。 一些python模块也是可以直接运行的脚本(它们在模块级别执行一些有用的工作)。
一般来说,最好使用绝对进口而不是相对进口。
1 2 3 4 5 6
| toplevel_package/
├── __init__.py
├── moduleA.py
└── subpackage
├── __init__.py
└── moduleB.py |
在moduleB中:
1
| from toplevel_package import moduleA |
如果您想将moduleB.py作为脚本运行,请确保toplevel_package的父目录位于sys.path中。
-
为什么在这种情况下不应该使用sys路径"hacks"?如果没有它们,Python很难在这里做你想做的事情。究竟什么是缺点?
-
@BT sys.path.append(path_to_parent)不应该是如何修复"import ../scriptA.py#我得到编译错误说"。""无效"问题的答案。有些情况下,更改sys.path可能是有用的,例如,如果python本身已经完成它或处理所有角落情况的3方模块正确完成它,例如,import autopath; autopath.add_toplevel_to_syspath()自动将toplevel_package的父目录添加到sys.path允许直接内部模块作为脚本(或在REPL中)从任何目录执行,而无需安装正确的PYTHONPATH或(virtualenv)。
-
@JFSebastian是否有某种功能的提议允许我们明确说出整个项目的主文件夹或包是什么,这样我们就不必关心将父目录添加到sys.path以便我们可以运行子模块也作为主文件或脚本?我有一个项目,我真的需要运行脚本作为主要或模块,导入,但我需要做大量的黑客添加路径到sys.path,使它们在两种情况下都可以工作。可以在virtualenv中工作或使用setuptools以某种方式工作吗?我真的很挣扎......
-
@nbro该功能称为pip install main-package。您可以运行"子模块"(只使用它们的绝对名称,例如python -ma.b.c)。如果不清楚;问
-
@jfs所以你建议每当我开始处理新的应用程序时,将toplevel_package添加到PYTHONPATH?
-
@Pietrko:答案讨论了如何从作为脚本运行的toplevel_package.subpackage.moduleB导入toplevel_package.moduleA。我不知道它与"新应用程序"有什么关系
-
"如果你想将moduleB.py作为脚本运行,那么请确保toplevel_package的父目录在你的sys.path中。"这句话是金子。这解决了我所有的问题,谢谢。
-
这个解决方案对我不起作用。它引发:"ImportError:没有名为toplevel_package的模块"
-
@smart阅读答案中的最后一句话。
-
这个解决方案适用于我当地的罚款但是当我在docker上构建它时会抛出错误。而不是我也将文件传输到另一个位置。如果你在docker上部署时遇到错误,请点击这一点,但这只是一个警告说明,以防你遇到同样的问题
来自文档:
您可以在包中执行此操作,但不能在直接运行的脚本中执行此操作。 从上面的链接:
Note that both explicit and implicit relative imports are based on the
name of the current module. Since the name of the main module is
always"__main__", modules intended for use as the main module of a
Python application should always use absolute imports.
如果创建导入A.B.B的脚本,则不会收到ValueError。
-
ValueError:在非包中尝试相对导入
-
@jgritty,那是因为你是在一个你直接运行的脚本中做的。
-
你是对的。如果您调用脚本然后导入脚本B,它将起作用。
-
@jgritty sys.path.append("..")是您正在寻找的
-
最后,6年后,我一直在寻找的代码片段!
如果要直接运行脚本,可以:
将FolderA的路径添加到环境变量(PYTHONPATH)。
在脚本中添加sys.path的路径。
然后:
1
| import module_you_wanted |