我需要在python脚本中设置一些环境变量,我希望所有从python调用的其他脚本(shell脚本),这些脚本将是子进程,可以看到设置的环境变量。这个值是一个数字。
如果我做os.environ["DEBUSSY"] = 1
,它会抱怨说1
必须是字符串。
我还想知道,一旦我设置了环境变量,如何在python中读取环境变量(在脚本的后面部分)。
环境变量必须是字符串,所以使用
os.environ["DEBUSSY"] = "1"
来设置变量DEBUSSY
为字符串1
。
以后要访问这个变量,只需使用。
print(os.environ["DEBUSSY"])
子进程会自动继承父进程的环境变量--不需要你做任何特殊操作。
你可能需要考虑一些进一步的方面来保证代码的健壮性。
当你把一个整数值的变量作为环境变量来存储时,可以尝试一下
os.environ['DEBUSSY'] = str(myintvariable)
那么对于检索,考虑到避免错误,你应该尝试用
os.environ.get('DEBUSSY', 'Not Set')
可能用'-1'。 for 'Not Set'
所以,把这一切放在一起
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)
os.environ
的行为就像一个python字典,所以可以执行所有常见的字典操作。
除了其他答案中提到的 "get "和 "set "操作外,我们还可以简单地检查一个键是否存在。
Python 3
在python 3中,字典使用in关键字而不是has_key。
>>> import os
>>> 'HOME' in os.environ # Check an existing env. variable
True
...
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
时,不会反映最新的值。
摘自[docs][1]。
这个映射是在第一次导入 os 模块时捕获的。
通常是在Python启动时作为处理site.py的一部分。 变化
在这之后对环境的影响没有反映在 >.os.environ。 os.environ,除了直接修改 os.environ 所做的修改。
os.environ.data
存储了所有的环境变量,是一个 dict 对象,它包含了所有的环境值。
>>> type(os.environ.data) # changed to _data since v3.2 (refer comment below)
<type 'dict'>
[1]: https://docs.python.org/2/library/os.html#os.environ "docs"。
你应该给环境变量分配字符串值。
os.environ["DEBUSSY"] = "1"
。
如果你想读取或打印环境变量,只需使用
print os.environ["DEBUSSY"]
。
这种改变只对分配给它的当前进程有效,不会永久改变该值。 子进程将自动继承父进程的环境。
[![在此输入图像描述][1]][1] 。
设置变量的方法。
使用键的项赋值方法:。
import os
os.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'
作为返回值。
方法2:。
os.environ['DEBUSSY'] # will throw an key error if not found!
方法3:。
'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
你可以使用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
当你使用环境变量(添加/修改/删除变量)时,一个好的做法是在函数完成时恢复之前的状态。
你可能需要类似于这个question中描述的modified_environ
上下文管理器来恢复环境变量。
经典的用法是:{{{9129953}}。
with modified_environ(DEBUSSY="1"):
call_my_function()
需要注意的是,如果你试图将环境变量设置为bash评估,它不会存储你所期望的东西。 例如:
from os import environ
environ["JAVA_HOME"] = "$(/usr/libexec/java_home)"
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 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)