今天我读了关于Python中的absolute and relative imports,我想知道当包含导入的脚本用作模块并且直接调用它时,是否有一种Python方式使导入工作。例如:
└── project
├── main.py
└── package
├── submoduleA.py
└── submoduleB.py
main.py
from package.submoduleA import submoduleAfunction
submoduleAfunction()
子模块b.py
def submoduleBfunction():
print('Hi from submoduleBfunction')
子模a.py
# Absolute import, works when called directly: python3 package/submoduleA.py
from submoduleB import submoduleBfunction
# Relative import, works when imported as module: python3 main.py
# from .submoduleB import submoduleBfunction
def submoduleAfunction():
submoduleBfunction()
if __name__=="__main__":
submoduleAfunction()
如你所见,我有绝对进口和相对进口。它们中的每一个都在特定的情况下工作。但是,有没有一种类似于Python的方法可以使这两种情况都有效呢?到目前为止,我已经完成了处理sys.path
的技巧,但我不确定这在任何情况下(即从解释器调用或在不同的操作系统中调用)都会起作用,或者即使这违反了任何建议
import sys
import pathlib
sys.path.append(str(pathlib.Path(__file__).parent.resolve()))
因为
submoduleA
是submoduleB
的“兄弟姐妹”,所以这实际上是一个隐式的相对导入。关于他们style guide说:当作为脚本运行
python3 package/submoduleA.py
时,它甚至可以工作的唯一原因是Python将脚本的目录前置到sys.path
。从docs开始:也就是说,目录
/path/to/package
被注入sys.path
,允许直接导入submoduleB
不应该使用隐式相对导入,那么应该使用什么来代替呢?没关系,您可以使用正确的绝对导入形式:
或相对导入:
只要已将
package
安装到环境中(安装包就是将代码放入位于sys.path
上的site-packages中),这两种方法都可以如果您必须以脚本形式直接运行
package/submoduleA.py
,即considered an anti-pattern,则需要使用绝对导入版本。在这种情况下,相对导入do not work。您需要改用python3 -m package.submoduleA
,以使相对导入版本正常工作一种可能是将绝对导入包含在
try
块中,然后捕获一个ImportException
。在出现异常的情况下,您可能将其用作模块,然后执行相对导入免责声明:
您的里程数可能会有所不同,我意识到我的答案并不能完全回答这个问题(使用相对导入)。我是罪魁祸首(我的错)
为我辩护:谷歌python避免相对导入返回540k次点击
我通常避免相对导入,因为它们似乎在这类事情上有太多的特殊情况,我非常喜欢在适当的时候直接将python文件作为脚本运行
例如,我的
constants.py
文件可以作为脚本运行—它将breakpoint()
,我可以检查它的内容,其中很多内容来自环境变量假设
project
的父目录位于Python路径中,我只会使用from project.package.submoduleA import submoduleAfunction
。这在所有情况下都有效(我发现显式导入的另一个好处是,我想将我的顶级包(
myproject
重命名为myproject2
)。所有内容都显式允许我快速sed
更改。请注意下面评论中Wim的评论)相关问题 更多 >
编程相关推荐