【问题标题】:Add folder to PYTHONPATH programmatically以编程方式将文件夹添加到 PYTHONPATH
【发布时间】:2021-11-19 04:26:36
【问题描述】:

环境变量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? 我只想更改系统环境变量以执行当前脚本

【问题讨论】:

  • 您要更改os.environ 中的值还是系统环境变量?如果是后者,应该是永久更改还是临时更改(即仅用于执行当前脚本)?
  • 我想更改系统环境变量只为了当前脚本的执行

标签: python windows pythonpath


【解决方案1】:

sys.pathos.environ 设置你想要的东西。您只是缺少两件事:

  • 每个进程都设置了一个环境变量,因此除非进程结束,否则无法从进程外部访问
  • os.system 在新的子 shell 中执行,因此 env var 不会影响您的进程。它在子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"] + &lt;separator&gt; + new path}),它基本上会打开一个新进程 - 即您可以为其他程序创建一个 Python 启动器并以这种方式为其准备环境。它里面的环境会受到影响,但是外面的环境仍然不会,因为你仍然需要从shell的进程上下文中访问shell,而不是从子进程(python进程)。

更多关于herehere的信息。

例子:

# 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"}
)

【讨论】:

  • A.) 这不是答案,B.) OP 正在使用 Windows。
  • 已针对 Windows 更新。其余的并没有真正改变。使用 sys 或 os 以编程方式操作它很好,但在保留父进程中的值时你是正确的 - 进一步解释。
  • @Tonechas 检查答案的更新,尤其是作为 Unix StackExchange 的链接部分。同样适用于 Windows。
  • 感谢您的帮助。我发现命令 python -c "print('set PYTHONPATH=%PYTHONPATH%;world')" &gt; out.bat 对于找出问题特别有启发性。
【解决方案2】:

如果您只想更改它以执行当前脚本,您只需在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])

【讨论】:

    【解决方案3】:

    我相信sys.path.append(...) 应该可以工作。 不要忘记导入sys

    【讨论】:

    • 这不能回答我的问题,因为我想更改 PYTHONPATH 而不是 PATH
    • @Tonechas It does.
    • @PeterBadida:OP 想要以编程方式更改环境变量的值,所以不。
    猜你喜欢
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2016-10-31
    • 2017-03-07
    • 2013-07-09
    • 2012-05-23
    • 2011-10-25
    相关资源
    最近更新 更多