以编程方式将文件夹添加到 PYTHONPATH

Add folder to PYTHONPATH programmatically

环境变量 PYTHONPATH 设置为 C:\Users\Me。我想向 PYTHONPATH 添加一个名为 code 的文件夹,该文件夹与我的脚本 (D:\Project) 位于同一目录中。这是我试过的:

test.py

import os
from pathlib import Path

print('BEFORE:', os.environ['PYTHONPATH'])

folder = Path(__file__).resolve().parent.joinpath('code')
print('FOLDER:', folder)

os.system(f'set PYTHONPATH={folder};%PYTHONPATH%')
print('AFTER:', os.environ['PYTHONPATH'])
样本运行:
D:\Project> dir /ad /b
code

D:\Project> dir *.py /b
test.py

D:\Project> python test.py
BEFORE: C:\Users\Me
FOLDER: D:\Project\code
AFTER: C:\Users\Me     <<< should be D:\Project\code;C:\Users\Me

我也试过这个:

import subprocess
subprocess.run(["set", f"PYTHONPATH={folder};%PYTHONPATH%"])

这就是我得到的:

FileNotFoundError: [WinError 2] The system cannot find the file specified

如何以编程方式将文件夹添加到 PYTHONPATH? 我只想为当前脚本的执行更改系统环境变量

我相信 sys.path.append(...) 应该有效。 不要忘记导入 sys.

sys.path as well as os.environ 设置你想要的东西。你只是错过了两件事:

  • 每个进程都设置了一个环境变量,因此无法从进程外部访问,除非进程结束后
  • os.system 在新的子 shell 中执行,因此您的进程不会影响环境变量。它在子 shell 中受到影响 ,然后退出。
C:\> set PYTHONPATH=hello; python
>>> from os import environ
>>> environ["PYTHONPATH"]
'hello'
>>> environ["PYTHONPATH"] = environ["PYTHONPATH"] + ";world"
>>> environ["PYTHONPATH"]
'hello;world'
>>> 
C:\> echo %PYTHONPATH%
# empty or "%PYTHONPATH%" string

为了保存价值,您需要利用 shell 来操纵环境。例如 export(或 Windows 上的 set):

set PYTHONPATH=hello
echo %PYTHONPATH%
# hello
python -c "print('set PYTHONPATH=%PYTHONPATH%;world')" > out.bat
out.bat
echo %PYTHONPATH%
# hello;world

或者,利用 subprocess.Popen(["command"], env={"PYTHONPATH": environ["PYTHONPATH"] + <separator> + new path}),这基本上会打开一个新进程 - 也就是说,您可以为其他一些程序创建一个 Python 启动器,并以这种方式为其准备环境。它里面的环境会受到影响,但是外面的环境仍然不会因为你仍然需要从shell的进程上下文中访问shell,而不是从child(python 进程)。

更多相关信息 here and here

示例:

# launcher.py
from subprocess import Popen

Popen(["python", "-c", "import os;print(os.environ.get('PYTHONPATH'))"])

Popen(
    ["python", "-c", "import os;print(os.environ.get('PYTHONPATH'))"],
    env={"PYTHONPATH": "hello"}
)

如果您只想为当前脚本的执行更改它,只需在 os.environ 映射中分配(或更改现有)值即可。下面的代码有点复杂,因为即使 os.environ[PYTHONPATH] 不是 最初设置为任何东西(就像我自己的系统一样),我也让它工作。

import os
from pathlib import Path

PYTHONPATH = 'PYTHONPATH'

try:
    pythonpath = os.environ[PYTHONPATH]
except KeyError:
    pythonpath = ''

print('BEFORE:', pythonpath)

folder = Path(__file__).resolve().parent.joinpath('code')
print(f'{folder=}')

pathlist = [str(folder)]
if pythonpath:
    pathlist.extend(pythonpath.split(os.pathsep))
print(f'{pathlist=}')

os.environ[PYTHONPATH] = os.pathsep.join(pathlist)
print('AFTER:', os.environ[PYTHONPATH])