如何在 Python 中设置环境变量?
- 2024-12-05 08:38:00
- admin 原创
- 145
问题描述:
我需要在 Python 脚本中设置一些环境变量,并且我希望从 Python 调用的所有其他脚本都能看到环境变量的设置。
如果我这么做,
os.environ["DEBUSSY"] = 1
它抱怨说那1
必须是一个字符串。
我还想知道一旦我设置了环境变量,如何在 Python 中读取它(在脚本的后半部分)。
解决方案 1:
环境变量必须是字符串,因此使用
import os
os.environ["DEBUSSY"] = "1"
将变量设置DEBUSSY
为字符串1
。
稍后要访问此变量,只需使用
print(os.environ["DEBUSSY"])
子进程自动继承父进程的环境——不需要您采取任何特殊操作。
解决方案 2:
您可能需要考虑代码稳健性的一些进一步的方面;
当您将整数值变量存储为环境变量时,请尝试
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:
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
再次调用将不会反映最新的值。
文档摘录:
首次导入 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'>
解决方案 4:
在使用此方法之前,请先阅读评论部分
我一直在尝试添加环境变量。我的目标是将一些用户信息存储到系统变量中,以便我可以将这些变量用于未来的解决方案,作为配置文件的替代方案。但是,下面代码中描述的方法对我没有任何帮助。
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 包的系统类中包装的 windows shell 命令,成功地将变量保存在窗口环境寄存器中。以下代码描述了这次成功的尝试。
os.system("SETX {0} {1} /M".format(key, value))
我希望这对你们中的一些人有帮助。
解决方案 5:
如果我执行 os.environ["DEBUSSY"] = 1,它会抱怨说 1 必须是字符串。
然后做
os.environ["DEBUSSY"] = "1"
我还想知道一旦我设置了环境变量,如何在 python 中读取它(在脚本的后半部分)。
只需使用os.environ["DEBUSSY"]
, 例如
some_value = os.environ["DEBUSSY"]
解决方案 6:
设置变量:
item 使用 key 的分配方法:
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!
方法 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
解决方案 7:
那怎么办os.environ["DEBUSSY"] = '1'
?环境变量始终是字符串。
解决方案 8:
您应该为环境变量分配字符串值。
os.environ["DEBUSSY"] = "1"
如果你想读取或打印环境变量,只需使用
print os.environ["DEBUSSY"]
此更改仅对分配该值的当前进程有效,不会永久更改该值。子进程将自动继承父进程的环境。
解决方案 9:
需要注意的是,如果您尝试将环境变量设置为 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 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}")
解决方案 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
解决方案 11:
当您使用环境变量(添加/修改/删除变量)时,一个好的做法是在函数完成时恢复以前的状态。
您可能需要类似modified_environ
本问题中描述的上下文管理器来恢复环境变量。
经典用法:
with modified_environ(DEBUSSY="1"):
call_my_function()
解决方案 12:
像这样设置环境变量:
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')
解决方案 13:
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"])
解决方案 14:
管理用户定义的环境变量的一个巧妙方法是将它们全部放在一个文本文件中,并在运行时加载它们。我们可以使用python-dotenv包来实现这一点,它允许我们导入这些变量。可以通过以下方式安装此包:
pip install python-dotenv
默认情况下,模块在当前目录中查找名为.env的文件。在此文件中定义所有变量,每行一个,如下所示:
DEBUSSY=1
PATH_TO_EXECUTABLE=/home/user_name/project/run.sh
然后按如下方式将它们导入到您的环境中:
from dotenv import load_dotenv
load_dotenv()
print(os.getenv('DEBUSSY'))
您可以将包含已定义变量的文件的路径指定为load_dotenv的可选参数。随后,可以通过os模块访问这些环境变量,如其他一些响应中所述。
解决方案 15:
我编写了这个小型上下文管理器,它仅在缩进块的持续时间内设置变量:
import os
from contextlib import contextmanager
@contextmanager
def extended_env(new_env_vars):
old_env = os.environ.copy()
os.environ.update(new_env_vars)
yield
os.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)
解决方案 16:
那么下面呢?
os.environ["DEBUSSY"] = '1'
debussy = int(os.environ.get('DEBUSSY'))
print(type(debussy))
<类‘int’>
解决方案 17:
有一个很好的现成的 Python 解决方案,名为pycrosskit。它将创建对 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 path
SysEnv.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 read
SysEnv.get_var(name, reg_path=default_reg_path, delete=False)
解决方案 18:
迟来的回答可能会帮助某人快速测试而无需更改代码。只需运行附加了环境变量的应用程序即可:
$ DEBUSSY=1 python3 api.py
您可以通过这种方式将环境变量传递给任何脚本。
解决方案 19:
如果您在使用 Flask 和 unittest 时遇到困难,请记住,如果您在任何方法之外设置变量,则导入应用程序时会读取此变量。这似乎微不足道,但可以为某些人省去一些麻烦。
例如,如果进入你的 Flask unittest:
导入应用程序
在方法中设置环境变量
setUp
。用来
app.test_client()
测试你的应用程序
第二步中的变量将不会被第三步看到,因为在执行第一步时该变量已经被读取了。
解决方案 20:
环境对于代码本身(而不是子进程)是冻结的,并且无法通过编程方式完成。
无论在哪个平台上,一个好的解决方案是将对 python 的调用包装在批处理文件中。例如:如果我在 Linux 上,批处理文件可能看起来像
export "DEBUSSY"="1"
python mycode.py