如何在Python中设置环境变量?

1177

我需要在Python脚本中设置一些环境变量,并且我希望所有从Python调用的其他脚本都能看到设置的环境变量。

如果我这样做:

os.environ["DEBUSSY"] = 1

它报错,说1必须是一个字符串。

我还想知道如何在Python中读取环境变量(在脚本的后半部分),一旦我设置了它。


20个回答

1468

环境变量必须是字符串,因此请使用

import os
os.environ["DEBUSSY"] = "1"

将变量DEBUSSY设置为字符串1

稍后要访问此变量,只需使用

print(os.environ["DEBUSSY"])

子进程会自动继承父进程的环境变量 -- 您无需采取特殊行动。


67
在某些平台上,修改os.environ并不会实际上修改当前进程或子进程的系统环境。有关更多信息,请参阅文档:https://docs.python.org/2/library/os.html#os.environ - Evan
20
@Evan,可能有一些历史版本的Unix不支持 putenv(),但对于这些Unix,你无能为力。我曾经使用过的旧版本AIX和HPUX也支持它。如果有人今天真的能找到一台不支持它的电脑,我严重怀疑他们是否能在那台电脑上运行Python. :) - Sven Marnach
11
注意:引用自 @Evan 的参考资料,对环境的此类更改会影响使用 os.system()、popen() 或 fork() 和 execv() 启动的子进程。 换句话说,请记住这种方法不会修改您的程序运行的方式,只会修改您的程序的子进程的运行方式。确实,您的程序可以设置和读取环境变量,但仅限于为其子进程配置的环境中。另请参见:更改当前进程环境。到目前为止,我还没有找到一种Python脚本可以修改其父进程环境的方法。 - CODE-REaD
1
刚刚测试了一下,在Windows上子进程确实也会继承修改后的环境变量。 - kizzx2
18
对于像我这样的新手,你首先需要输入“import os”,否则它不会起作用。 - Harry
显示剩余2条评论

160

为了使代码更加健壮,您可能需要考虑一些其他方面;

当您将一个整型变量存储为环境变量时,请尝试

os.environ['DEBUSSY'] = str(myintvariable)

那么对于检索来说,为了避免错误,你应该尝试:

os.environ.get('DEBUSSY', 'Not Set')

可能将“未设置”替换为“-1”

因此,将所有这些放在一起

myintvariable = 1
os.environ['DEBUSSY'] = str(myintvariable)
strauss = int(os.environ.get('STRAUSS', '-1'))
# NB KeyError <=> strauss = os.environ['STRAUSS']
debussy = int(os.environ.get('DEBUSSY', '-1'))

print "%s %u, %s %u" % ('Strauss', strauss, 'Debussy', debussy)

3
您能告诉我如何在Linux机器上设置变量吗?这段代码在所有平台上都相同吗? - Anurag-Sharma
6
将-1用于表示缺失的整数很少是有意义的。更好的方法是使用 myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None,这样如果没有提供数字,则为None。 - Benjamin Atkin
1
如果您正在处理整数,-1是有意义的。虽然我可能会将变量/常量设置为未设置的值(例如,value_not_set ='-1')。然后,您可以使用debussy = int(os.environ.get('DEBUSSY', value_not_set)) - yeOldeDataSmythe

121

os.environ 行为类似于Python字典,因此可以执行所有常见的字典操作。除了其他答案中提到的 getset 操作之外,我们还可以简单地检查一个键是否存在。键和值应该存储为字符串

Python 3

对于Python 3,字典使用in 关键字而不是 has_key

>>> import os
>>> 'HOME' in os.environ  # Check an existing env. variable
True
...

Python 2

:Python 2
>>> import os
>>> os.environ.has_key('HOME')  # Check an existing env. variable
True
>>> os.environ.has_key('FOO')   # Check for a non existing variable
False
>>> os.environ['FOO'] = '1'     # Set a new env. variable (String value)
>>> os.environ.has_key('FOO')
True
>>> os.environ.get('FOO')       # Retrieve the value
'1'

注意使用os.environ时有一件重要的事情:

虽然子进程会继承父进程的环境变量,但最近我遇到了一个问题并发现如果您的Python脚本正在运行时有其他脚本更新环境变量,则再次调用os.environ 将不会反映最新值

来自文档的摘录:

此映射在第一次导入 os 模块时进行捕获,通常在处理 site.py 作为 Python 启动的一部分时进行。在此之后对环境所做的更改不会反映在 os.environ 中,除非通过直接修改 os.environ 所做的更改。

os.environ.data 存储所有环境变量,是一个包含所有环境值的 dict 对象:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>

8
进程环境变量是在创建进程时设置的。之后进行的更改不会影响进程自身的环境变量副本。这适用于所有进程,而不仅仅是Python。此外,在Python 3.2中,os.environ.data被重命名为os.environ._data,下划线前缀表示你不应该直接读取它。无论如何,os.environ._data也不会具有更新后的值。 - Al Sweigart
是的,我现在明白了。我想与其他寻找答案的人分享我的最初惊讶。感谢指出自3.2以来变量名称的更新,我会更新答案。 - sisanared
os.environ的行为类似于Python字典,因此可以执行所有常见的字典操作。除了提到的获取和设置操作之外...”它没有.set()方法,只有.setdefault()方法。 - smci

43

在使用此方法之前,请查看评论部分

我一直在尝试添加环境变量。我的目标是将某些用户信息存储到系统变量中,以便我可以将这些变量用于未来的解决方案,作为配置文件的替代方法。 然而,下面代码中描述的方法并没有帮助我。

import os
os.environ["variable_1"] = "value_1"
os.environ["variable_2"] = "value_2"
# To Verify above code
os.environ.get("variable_1")
os.environ.get("variable_2")

这个简单的代码块运行良好,但是这些变量存在于各自的进程中,因此您在Windows系统设置的环境变量选项卡中找不到它们。以上代码基本上没有达到我的目的。这个问题在这里讨论:变量保存问题

os.environ.putenv(key, value)

又一次不成功的尝试。最终,我通过模仿 os 包中 system 类包装的 Windows shell 命令,成功地将变量保存在窗口环境注册表中。以下代码描述了这个成功的尝试。

os.system("SETX {0} {1} /M".format(key, value))
我希望这对你们中的一些人有所帮助。

14
这是一个非常糟糕的想法!变量将永久存储在系统中,您只能通过编辑注册表来删除它!(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment)。当您建议这样的事情时,您应该至少警告人们!(但也许您甚至没有意识到这一点!) - Apostolos
4
是的,这里的想法是添加一个永久变量。我应该提到这一点。感谢您的更新。在答案开头描述的方法确实会添加仅存在于该进程中的环境变量,这是个人选择的问题,而我需要永久保存。 - Sourabh Desai
3
我认为这根本不是这个想法。首先,问题或其描述没有提到任何类似的内容。因此,逻辑上可以假定,提问者想要创建一个只能被其他脚本等使用的持久性变量,而不是在注册表中创建一个永久性变量!
我承认我的评论有些激进,但你让我浪费了很多时间,直到我找到如何从我仅用于测试的环境中删除一个永久性变量!!
- Apostolos
8
实际上,这比永久注册表存储更糟糕。如果您将setx用于像"PATH"变量这样重要的东西,当该变量超过1024个字符时,您整个现有的环境配置都会被破坏。也没有办法撤销它。不要使用它。即使微软也不知道得更好。 - Amit Naidu

25

如果我执行 os.environ["DEBUSSY"] = 1,它会报错说 1 必须是字符串。

那么可以这样做:

os.environ["DEBUSSY"] = "1"

我也想知道如何在 Python 中读取环境变量(在脚本的后面部分),一旦我设置了它。

只需使用os.environ["DEBUSSY"],如下所示:

some_value = os.environ["DEBUSSY"]

23

设置变量:

使用键进行项目分配的方法:

import os    
os.environ['DEBUSSY'] = '1'  #Environ Variable must be string not Int

获取或检查其是否存在,因为os.environ是一个实例,您可以尝试对象方式。

方法1:

os.environ.get('DEBUSSY') # this is error free method if not will return None by default

将会得到'1'作为返回值

方法2:

os.environ['DEBUSSY'] # will throw an key error if not found!

方法三:

'DEBUSSY' in os.environ  # will return Boolean True/False

第四种方法:

os.environ.has_key('DEBUSSY') #last 2 methods are Boolean Return so can use for conditional statements

17

在这里,os.environ["DEBUSSY"] = '1' 是什么意思呢?环境变量总是字符串。


17

您需要将字符串值分配给环境变量。

os.environ["DEBUSSY"] = "1"

如果您想要读取或打印环境变量,只需使用

print os.environ["DEBUSSY"]

这些更改仅对分配它的当前进程有效,不会永久更改该值。子进程将自动继承父进程的环境。

enter image description here


7
这些更改仅对当前分配的流程生效,不会永久更改该值。 这回答了我对设置环境变量范围的问题。 - spitfiredd
2
如果我退出Python shell,之前设置的操作系统环境将会消失。 - MeadowMuffins
如何在Windows中设置环境变量?我尝试使用set [<name>=[<value>]],但它只对当前运行的进程有效。当我关闭cmd时,它就不存在了,即使它是打开的,其他程序也看不到它。 - Filip

14

请注意,如果您尝试将环境变量设置为bash评估,它不会保存您期望的内容。例如:

from os import environ

environ["JAVA_HOME"] = "$(/usr/libexec/java_home)"

这不会像在Shell中那样进行评估,因此您将获得文字表达式$(/usr/libexec/java_home),而不是路径/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home

确保在设置环境变量之前对其进行评估,如下所示:

from os import environ
from subprocess import Popen, PIPE

bash_variable = "$(/usr/libexec/java_home)"
capture = Popen(f"echo {bash_variable}", stdout=PIPE, shell=True)
std_out, std_err = capture.communicate()
return_code = capture.returncode

if return_code == 0:
    evaluated_env = std_out.decode().strip()
    environ["JAVA_HOME"] = evaluated_env
else:
    print(f"Error: Unable to find environment variable {bash_variable}")

12

你可以使用os.environ字典来访问环境变量。

现在,我遇到的一个问题是,如果我尝试使用os.system运行一个批处理文件来设置你的环境变量(在**.bat*文件中使用SET命令),它实际上不会为你的python环境设置它们(而是在通过os.system函数创建的子进程中设置)。要想在python环境中真正设置这些变量,我使用了这个脚本:

import re
import system
import os

def setEnvBat(batFilePath, verbose = False):
    SetEnvPattern = re.compile("set (\w+)(?:=)(.*)$", re.MULTILINE)
    SetEnvFile = open(batFilePath, "r")
    SetEnvText = SetEnvFile.read()
    SetEnvMatchList = re.findall(SetEnvPattern, SetEnvText)

    for SetEnvMatch in SetEnvMatchList:
        VarName=SetEnvMatch[0]
        VarValue=SetEnvMatch[1]
        if verbose:
            print "%s=%s"%(VarName,VarValue)
        os.environ[VarName]=VarValue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接