如何在Python中设置环境变量

pra*_*ada 564 python environment-variables

我需要在python脚本中设置一些环境变量,我希望从python(shell脚本)调用的所有其他脚本都是子进程,以查看环境变量集.该值是一个数字.

如果我这样做os.environ["DEBUSSY"] = 1,它抱怨说1必须是字符串.我也想知道在设置之后如何在python中读取环境变量(在脚本的后面部分).

Sve*_*ach 679

环境变量必须是字符串,所以使用

os.environ["DEBUSSY"] = "1"
Run Code Online (Sandbox Code Playgroud)

将变量DEBUSSY设置为字符串1.要稍后访问此变量,只需使用

print(os.environ["DEBUSSY"])
Run Code Online (Sandbox Code Playgroud)

子进程自动继承父进程的环境 - 您无需执行任何特殊操作.

  • 在某些平台上,修改os.environ实际上不会为当前进程或子进程修改系统环境.有关详细信息,请参阅文档:https://docs.python.org/2/library/os.html#os.environ (13认同)
  • @Evan可能有一些Unix的历史变种不支持`putenv()`,但对于那些Unixen,你无论如何也无能为力.即使是我使用的旧版AIX和HPUX也支持它.如果有人实际上能够找到今天不支持它的计算机,我怀疑他们将能够在该计算机上运行Python.:) (6认同)
  • **警告:**引用@Evan的上述引用,*环境的此类更改会影响以os.system(),popen()或fork()和execv()开头的子流程。*换句话说,请记住这种方法不会修改程序的运行方式,只会修改程序的子级运行方式。没错,您的程序可以设置和读取环境变量,但只能从其为其子级配置的环境中进行。另请参阅:[更改当前过程环境](http://stackoverflow.com/q/1178094/5025060)。到目前为止,我还没有找到Python脚本修改其父环境的方法。 (3认同)
  • 对于像我这样的菜鸟来说,你必须先输入“import os”,否则这是行不通的。 (3认同)

Mar*_*ark 106

您可能需要考虑代码稳健性的其他方面;

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

os.environ['DEBUSSY'] = str(myintvariable)
Run Code Online (Sandbox Code Playgroud)

然后进行检索,考虑避免错误,你应该尝试

os.environ.get('DEBUSSY', 'Not Set')
Run Code Online (Sandbox Code Playgroud)

可能用'-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)
Run Code Online (Sandbox Code Playgroud)

  • 你能说出如何在Linux机器上设置变量,所有平台的代码是否相同? (3认同)
  • 对于缺少的整数,将-1存储很少。如果os.environ.get('MYVAR','')!=''else None`更好的选择是`myvar = int(os.environ.get('MYVAR'))-这样,如果没有提供号码 (2认同)

sis*_*red 49

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

Python 2

>>> import os
>>> 'HOME' in os.environ  # Check an existing env. variable
True
...
Run Code Online (Sandbox Code Playgroud)

Python 3

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

>>> 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'
Run Code Online (Sandbox Code Playgroud)

关于使用有一个重要的注意事项os.environ:

虽然子进程从父进程继承环境,但我最近遇到了一个问题并且想通了,如果在python脚本运行时有其他脚本更新环境,os.environ再次调用将不会反映最新的值.

摘自文档:

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

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

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

  • 进程的环境变量是在创建进程时设置的。在此之后所做的任何更改都不会影响进程自己的环境变量副本。这对所有进程都是通用的,而不仅仅是 Python。此外,`os.environ.data` 在 Python 3.2 中被重命名为 `os.environ._data`,下划线前缀表明你不应该直接读取它。无论如何,`os.environ._data` 无论如何都不会更新值。 (5认同)

Sou*_*sai 28

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

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

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")
Run Code Online (Sandbox Code Playgroud)

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

os.environ.putenv(key, value)
Run Code Online (Sandbox Code Playgroud)

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

os.system("SETX {0} {1} /M".format(key, value))
Run Code Online (Sandbox Code Playgroud)

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

  • 这是一个非常糟糕的主意!该变量将永久存储在系统中,您只能**通过编辑注册表**来删除它!(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment)。当你提出这样的事情时,你至少应该警告人们!(但也许你根本不知道这一点!) (5认同)
  • 是的,添加一个永久变量就是这里的想法。我应该提到这一点。感谢更新。答案开头描述的方法确实添加了仅存在于该进程中的环境变量,这是选择的问题,我需要永久保存。 (4认同)
  • 它实际上比永久注册表存储更糟糕。`setx` 可以截断你的环境变量。如果您将它用于诸如“PATH”变量之类的重要内容,那么当变量长度超过 1024 个字符时,您的整个现有环境配置将被破坏。也没有办法“撤消”这一点。不要使用它。即使是微软[也不知道](https://github.com/dotnet/docs/issues/21353)。 (4认同)
  • 我认为这根本不是这个想法。一方面,问题或其描述没有提及类似的内容。然后,从逻辑上讲,假设提问者只想创建一个可由其他脚本等使用的**持久**变量,而不是注册表中的**永久**变量!现在,我承认我的评论很激进,但是你让我损失了很多时间,直到我找到如何从我仅为测试而创建的环境中删除**永久**变量! (3认同)

Jim*_*som 20

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

然后做

os.environ["DEBUSSY"] = "1"
Run Code Online (Sandbox Code Playgroud)

我也想知道如何设置它后如何在python中读取环境变量(在脚本的后半部分).

就像使用os.environ["DEBUSSY"]一样

some_value = os.environ["DEBUSSY"]
Run Code Online (Sandbox Code Playgroud)


Rej*_*ran 15

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

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

如果您想阅读或打印环境变量,请使用

print os.environ["DEBUSSY"]

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

在此输入图像描述

  • "此更改仅对分配的当前进程有效,不会永久更改值."这回答了我对设置环境变量的范围的问题. (3认同)
  • 如果我退出python shell,那么之前设置的os environment就没有了。 (2认同)

Thi*_*ter 14

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


Moh*_*med 14

to Set Variable:

item Assignment method using key:

import os    
os.environ['DEBUSSY'] = '1'  #Environ Variable must be string not Int
Run Code Online (Sandbox Code Playgroud)

to get or to check whether its existed or not,

since os.environ is an instance you can try object way.

Method 1:

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

will get '1' as return value

Method 2:

os.environ['DEBUSSY'] # will throw an key error if not found!
Run Code Online (Sandbox Code Playgroud)

Method 3:

'DEBUSSY' in os.environ  # will return Boolean True/False
Run Code Online (Sandbox Code Playgroud)

Method 4:

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


小智 10

您可以使用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
Run Code Online (Sandbox Code Playgroud)


Lau*_*RTE 8

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

您可能需要类似modified_environ上下文管理器在此问题中描述的内容来恢复环境变量.

经典用法:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Run Code Online (Sandbox Code Playgroud)


小智 8

像这样设置环境变量:

import os

 # Set environment variables
 os.environ['API_USER'] = 'username'
 os.environ['API_PASSWORD'] = 'secret'

 # Get environment variables
 USER = os.getenv('API_USER')
 PASSWORD = os.environ.get('API_PASSWORD')
Run Code Online (Sandbox Code Playgroud)


Jos*_*eia 7

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

from os import environ

environ["JAVA_HOME"] = "$(/usr/libexec/java_home)"
Run Code Online (Sandbox Code Playgroud)

这不会像在shell中那样对它求值,因此,您无需获取/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home路径就可以获取文字表达式$(/usr/libexec/java_home)

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

from os import environ
from subprocess import Popen, PIPE

bash_variable = "$(/usr/libexec/java_home)"
capture = Popen("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("Error: Unable to find environment variable " + bash_variable)
Run Code Online (Sandbox Code Playgroud)


Sab*_*rov 7

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

确保将环境变量设置为字符串,而不是整数。否则会扔 TypeError

import os

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

print(os.environ["DEBUSSY"])

Run Code Online (Sandbox Code Playgroud)


sha*_*rhp 6

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

pip install python-dotenv
Run Code Online (Sandbox Code Playgroud)

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

DEBUSSY=1    
PATH_TO_EXECUTABLE=/home/user_name/project/run.sh
Run Code Online (Sandbox Code Playgroud)

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

from dotenv import load_dotenv
load_dotenv()

print(os.getenv('DEBUSSY'))
Run Code Online (Sandbox Code Playgroud)

您可以将包含已定义变量的文件的路径指定为load_dotenv的可选参数。随后,可以通过os模块访问这些环境变量,如其他一些响应中所述。