繁体   English   中英

如何在不中断上层导入的情况下从子目录运行 Python 脚本?

[英]How do I run a Python script from a subdirectory without breaking upper-level imports?

我有这样一个非常简单的场景:

example/
    common.py
    folder1/
        script.py

其中script.py文件应该导入common.py模块。

如果我cd进入folder1/并运行脚本(即通过在命令行上调用python3 script.py ),导入会中断并出现常见错误ModuleNotFoundError: No module named 'common'

我知道我可以通过在每个子目录中添加__init__.py文件将整个父文件夹变成 package,但是这个解决方案仍然阻止我直接从folder1/中运行脚本。

我怎样才能解决这个问题?

如果需要将父目录添加到搜索路径,则可以始终执行以下操作:

import os
import sys

DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, DIR)

os.path.realpath(__file__)获取文件的realpath, os.path.dirname获取该文件的目录名。 这样做两次获取example目录。 现在,由于这被添加到搜索路径,您可以导入common

但是,您应该考虑使用专用scriptsbin目录,而不是尝试从子目录运行脚本。 考虑编写库,并导入此库而不是单个文件。

如果将两个目录都转换为python包,并且顶层目录在PYTHONPATH中,则可以像这样运行script.py:

python3 -m example.folder1.script
import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

来自folder1.script导入....

如果它很简单,我们可能会这样做,但不幸的是,Python不会如何加载代码。

模块布局的方式可能意味着它们在不同版本的Python中以不同方式导入。 Namepsace包也改变了这种行为,其中多个完全不同的目录可以在其他模块下提供模块。 作为脚本运行的文件意味着其sys.path更改。 pth文件可以更多地修改路径。 如果我们开始寻找上升和上升的导入,我们最终将开始离开工作区并扫描驱动器(这具有不良影响)。 一个名字最终可能意味着在两个不同的地方有两件事,这在我们的分析中有其自身的不良影响(持久性,一个,以及其他事物)。 所有这些意味着我们必须权衡我们想要/可行的行为; 我们可能非常非常宽松,但是你可能会去运行代码并且它会中断,你会想知道为什么编辑器事先没有告诉你有什么问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM