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

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

如果我这么做,

os.environ["DEBUSSY"] = 1

它抱怨说1必须是一个字符串。

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

1472768 次浏览

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

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

将变量DEBUSSY设置为字符串1

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

print(os.environ["DEBUSSY"])

子进程自动继承父进程的环境——不需要您的特殊操作。

os.environ["DEBUSSY"] = '1'呢?环境变量总是字符串。

如果我os.environ["DEBUSSY"]=1,则抱怨说1必须是字符串。

那就去做

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

我也想知道怎么读python中的环境变量脚本的后面部分)一旦我设置它。

只需使用os.environ["DEBUSSY"],如

some_value = os.environ["DEBUSSY"]

您可能需要考虑代码健壮性的一些进一步方面;

当您将整数值变量存储为环境变量时,请尝试

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

然后对于检索,考虑到为了避免错误,您应该尝试

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

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

所以,把这一切放在一起

myintvariable = 1os.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)

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

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

import reimport systemimport 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

您应该将字符串值分配给环境变量。

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

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

print os.environ["DEBUSSY"]

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

在此处输入图像描述

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

python3

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

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

python2

>>> import os>>> os.environ.has_key('HOME')  # Check an existing env. variableTrue>>> os.environ.has_key('FOO')   # Check for a non existing variableFalse>>> 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模块时捕获的,通常在Python启动期间作为处理site.py.更改的一部分对环境的影响在这段时间后没有反映在os.environ,除了直接修改os.environ所做的更改。

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

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

当您使用环境变量(添加/修改/删除变量)时,一个好的做法是在函数完成时恢复以前的状态。

您可能需要类似于问题中描述的modified_environ上下文管理器来恢复环境变量。

经典用法:

with modified_environ(DEBUSSY="1"):call_my_function()

设置变量:

使用键的项目分配方法:

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

以获取或检查它是否存在,

由于os.environ是一个实例,您可以尝试对象方式。

方法一:

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

将获取'1'作为返回值

方法二:

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

方法三:

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

方法4:

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

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

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

这不会像在shell中那样计算它,因此不会将/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home作为路径,而是将获得文字表达式$(/usr/libexec/java_home)

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

from os import environfrom 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_envelse:print(f"Error: Unable to find environment variable {bash_variable}")

在使用此方法之前,请浏览评论部分

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

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

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

os.environ.putenv(key, value)

又一次失败的尝试。所以,最后,我通过模仿包装在os包的系统类中的windows shell命令,成功地将变量保存在窗口环境寄存器中。以下代码描述了这次成功的尝试。

os.system("SETX {0} {1} /M".format(key, value))

我希望这对你们中的一些人有所帮助。

如果环境中不存在变量,请使用setdefault函数设置新变量。

确保将环境变量设置为字符串,而不是int。否则将抛出TypeError

import os
if not os.environ.get("DEBUSSY"):os.environ.setdefault("DEBUSSY","1")else:os.environ["DEBUSSY"] = "1"
print(os.environ["DEBUSSY"])

有一个很好的开箱即用的Python解决方案,称为纵横短剧。它将为Linux和Windows创建持久的环境变量。

用法:

# Will Set Persistent Value for Variable in System# * subkey works only for windows like file in folder# * reg_path works only for windows as register pathSysEnv.set_var(name, value, subkey, reg_path=default_reg_path)
# Will Get Persistent Value for Variable in System# * reg_path works only for windows as register path# * delete, deletes key from environment and its subkeys after readSysEnv.get_var(name, reg_path=default_reg_path, delete=False)

如果您正在使用Flask和unittest,请记住,如果您在任何方法之外设置变量,则会在导入应用程序时读取此变量。可能看起来微不足道,但可以为某人节省一些头痛。

例如,如果进入你的烧瓶单元测试你:

  1. 导入应用
  2. setUp方法中设置环境变量。
  3. 使用app.test_client()测试您的应用程序

进入第二步的变量将不会被第三步看到,因为在执行第一步时已经读取了该变量。

我写了这个小上下文管理器,它只设置缩进块持续时间的变量:

import osfrom contextlib import contextmanager
@contextmanagerdef extended_env(new_env_vars):old_env = os.environ.copy()os.environ.update(new_env_vars)yieldos.environ.clear()os.environ.update(old_env)

示例用法(Windows为%,Linux为$):

import subprocess
subprocess.run("echo $ENVTEST %ENVTEST%", shell=True)
with extended_env({"ENVTEST": "17"}):subprocess.run("echo $ENVTEST %ENVTEST%", shell=True)
subprocess.run("echo $ENVTEST %ENVTEST%", shell=True)

以下情况如何?

os.environ["DEBUSSY"] = '1'debussy = int(os.environ.get('DEBUSSY'))print(type(debussy))

<类'int'>

管理用户定义的环境变量的一个巧妙方法是将它们全部放在一个文本文件中并在运行时加载它们。我们可以使用python-dotenv包来实现这一点,它允许我们导入这些变量。这个包可以通过以下方式安装:

pip install python-dotenv

默认情况下,模块在当前目录中查找一个名为. env的文件。定义此文件中的所有变量,每行一个,如下所示:

DEBUSSY=1PATH_TO_EXECUTABLE=/home/user_name/project/run.sh

然后将它们导入您的环境,如下所示:

from dotenv import load_dotenvload_dotenv()

您可以指定包含定义变量的文件的路径作为load_dotenv的可选参数。随后,这些环境变量可以通过os模块正常访问。

延迟回答可能有助于某人在不更改代码的情况下快速测试。只需运行您的应用程序并附加环境变量,如下所示:

 $ DEBUSSY=1 python3 api.py

您可以通过这种方式将env vars传递给任何脚本。

代码本身(不是子进程)的环境被冻结,无法以编程方式完成。

无论什么平台,一个好的解决方案都是将对python的调用包装在批处理文件中。例如:如果我在linux上,批处理文件可能看起来像

export "DEBUSSY"="1"python mycode.py