[英]How do I run a Python script from a subdirectory without breaking upper-level imports?
I have a very simple scenario like this:我有这样一个非常简单的场景:
example/
common.py
folder1/
script.py
where script.py
file should import common.py
module.其中
script.py
文件应该导入common.py
模块。
If I cd
into folder1/
and run the script (ie by calling python3 script.py
on the command line), the import breaks with the usual error ModuleNotFoundError: No module named 'common'
.如果我
cd
进入folder1/
并运行脚本(即通过在命令行上调用python3 script.py
),导入会中断并出现常见错误ModuleNotFoundError: No module named 'common'
。
I know I could turn the whole parent folder into a package by adding __init__.py
files in each subdirectory, however this solution still prevents me to run the script directly from inside folder1/
.我知道我可以通过在每个子目录中添加
__init__.py
文件将整个父文件夹变成 package,但是这个解决方案仍然阻止我直接从folder1/
中运行脚本。
How can I fix this?我怎样才能解决这个问题?
If you need to add a parent directory to the search path, you can always do: 如果需要将父目录添加到搜索路径,则可以始终执行以下操作:
import os
import sys
DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, DIR)
os.path.realpath(__file__)
gets the realpath to the file, and os.path.dirname
gets the directory name of this file. os.path.realpath(__file__)
获取文件的realpath, os.path.dirname
获取该文件的目录名。 Doing it twice gets the example
directory here. 这样做两次获取
example
目录。 Now, since this is added to the search path, you can import common
. 现在,由于这被添加到搜索路径,您可以导入
common
。
However, you should really consider having a dedicated scripts
or bin
directory, rather than try to run scripts from subdirectories. 但是,您应该考虑使用专用
scripts
或bin
目录,而不是尝试从子目录运行脚本。 Think about writing a library, and import this library rather than individual files. 考虑编写库,并导入此库而不是单个文件。
如果将两个目录都转换为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()
from folder1.script import .... 来自folder1.script导入....
If it were that simple, we'd probably be doing it, but that's unfortunately not how Python's going to go load the code either. 如果它很简单,我们可能会这样做,但不幸的是,Python不会如何加载代码。
The way modules are laid out can mean they are imported differently in different versions of Python. 模块布局的方式可能意味着它们在不同版本的Python中以不同方式导入。 Namepsace packages change this behavior as well, where multiple completely different directories can provide modules underneath other modules.
Namepsace包也改变了这种行为,其中多个完全不同的目录可以在其他模块下提供模块。 A file being run as a script means its sys.path changes.
作为脚本运行的文件意味着其sys.path更改。 pth files can modify paths even more.
pth文件可以更多地修改路径。 If we go start looking for imports up and up and up, we'll eventually start leaving the workspace and scanning through the drive (which has bad implications).
如果我们开始寻找上升和上升的导入,我们最终将开始离开工作区并扫描驱动器(这具有不良影响)。 One name could end up meaning two things in two different places, which has its own bad implications in our analysis (persistence, for one, along with other things).
一个名字最终可能意味着在两个不同的地方有两件事,这在我们的分析中有其自身的不良影响(持久性,一个,以及其他事物)。 All of these mean we have to make tradeoffs for what behavior we want/can feasibly do;
所有这些意味着我们必须权衡我们想要/可行的行为; we could be very, very loose, but then you may go to run the code and it break and you'd wonder why the editor didn't tell you something was wrong beforehand.
我们可能非常非常宽松,但是你可能会去运行代码并且它会中断,你会想知道为什么编辑器事先没有告诉你有什么问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.