简体   繁体   English

Python如何设置环境变量?

[英]How to set environment variables in Python?

I need to set some environment variables in the Python script and I want all the other scripts that are called from Python to see the environment variables' set.我需要在 Python 脚本中设置一些环境变量,我希望从 Python 调用的所有其他脚本都能看到环境变量的设置。

If I do,如果我做,

os.environ["DEBUSSY"] = 1

it complains saying that 1 has to be a string.它抱怨说1必须是一个字符串。

I also want to know how to read the environment variables in Python (in the latter part of the script) once I set it.我还想知道设置后如何读取 Python 中的环境变量(在脚本的后半部分)。

Environment variables must be strings, so use环境变量必须是字符串,所以使用

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

to set the variable DEBUSSY to the string 1 .将变量DEBUSSY设置为字符串1

To access this variable later, simply use:要稍后访问此变量,只需使用:

print(os.environ["DEBUSSY"])

Child processes automatically inherit the environment variables of the parent process -- no special action on your part is required.子进程自动继承父进程的环境变量——不需要您采取任何特殊行动。

You may need to consider some further aspects for code robustness;您可能需要考虑代码稳健性的其他方面;

when you're storing an integer-valued variable as an environment variable, try当您将整数值变量存储为环境变量时,请尝试

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

then for retrieval, consider that to avoid errors, you should try然后为了检索,考虑到避免错误,你应该尝试

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

possibly substitute '-1' for 'Not Set'可能用“-1”代替“未设置”

so, to put that all together所以,把这一切放在一起

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 behaves like a python dictionary, so all the common dictionary operations can be performed. os.environ的行为类似于 python 字典,因此可以执行所有常见的字典操作。 In addition to the get and set operations mentioned in the other answers, we can also simply check if a key exists.除了其他答案中提到的getset操作之外,我们还可以简单地检查一个键是否存在。 The keys and values should be stored as strings .键和值应存储为字符串

Python 3蟒蛇 3

For python 3, dictionaries use the in keyword instead of has_key对于 python 3,字典使用in关键字而不是has_key

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

Python 2蟒蛇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'

There is one important thing to note about using os.environ :使用os.environ需要注意一件重要的事情:

Although child processes inherit the environment from the parent process, I had run into an issue recently and figured out, if you have other scripts updating the environment while your python script is running, calling os.environ again will not reflect the latest values .虽然子进程从父进程继承了环境,但我最近遇到了一个问题,并且发现,如果您在 python 脚本运行时有其他脚本更新环境,再次调用os.environ将不会反映最新的值

Excerpt from the docs : 文档摘录:

This mapping is captured the first time the os module is imported, typically during Python startup as part of processing site.py.在第一次导入 os 模块时捕获此映射,通常在 Python 启动期间作为处理 site.py 的一部分。 Changes to the environment made after this time are not reflected in os.environ, except for changes made by modifying os.environ directly.在此时间之后对环境所做的更改不会反映在 os.environ 中,但直接修改 os.environ 所做的更改除外。

os.environ.data which stores all the environment variables, is a dict object, which contains all the environment values: os.environ.data存储所有环境变量,是一个 dict 对象,其中包含所有环境值:

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

Before using this method please go through Comments Sections在使用此方法之前,请浏览评论部分

I have been trying to add environment variables.我一直在尝试添加环境变量。 My goal was to store some user information to system variables such that I can use those variables for future solutions, as an alternative to config files.我的目标是将一些用户信息存储到系统变量中,以便我可以将这些变量用于未来的解决方案,作为配置文件的替代方案。 However, the method described in the code below did not help me at all.但是,下面代码中描述的方法根本没有帮助我。

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")

This simple code block works well, however, these variables exist inside the respective processes such that you will not find them in the environment variables tab of windows system settings.这个简单的代码块运行良好,但是,这些变量存在于各个进程中,因此您不会在 Windows 系统设置的环境变量选项卡中找到它们。 Pretty much above code did not serve my purpose.上面的代码几乎没有达到我的目的。 This problem is discussed here: variable save problem这个问题在这里讨论: 变量保存问题

os.environ.putenv(key, value)

Another unsuccessful attempt.又一次失败的尝试。 So, finally, I managed to save variables successfully inside the window environment register by mimicking the windows shell commands wrapped inside the system class of os package.所以,最后,我通过模仿包装在 os 包的系统类中的 windows shell 命令,成功地将变量保存在窗口环境寄存器中。 The following code describes this successful attempt.下面的代码描述了这个成功的尝试。

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

I hope this will be helpful for some of you.我希望这对你们中的一些人有所帮助。

if i do os.environ["DEBUSSY"] = 1, it complains saying that 1 has to be string.如果我做 os.environ["DEBUSSY"] = 1,它会抱怨说 1 必须是字符串。

Then do然后做

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

I also want to know how to read the environment variables in python(in the later part of the script) once i set it.我还想知道一旦我设置了它,如何在 python 中读取环境变量(在脚本的后面部分)。

Just use os.environ["DEBUSSY"] , as in只需使用os.environ["DEBUSSY"] ,如

some_value = os.environ["DEBUSSY"]

to Set Variable:设置变量:

item Assignment method using key: item 使用 key 的赋值方法:

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

to get or to check whether its existed or not,获取或检查它是否存在,

since os.environ is an instance you can try object way.由于os.environ是一个实例,您可以尝试对象方式。

Method 1:方法一:

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

will get '1' as return value将获得'1'作为返回值

Method 2:方法二:

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

Method 3:方法三:

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

Method 4:方法四:

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

What about os.environ["DEBUSSY"] = '1' ? os.environ["DEBUSSY"] = '1'怎么样? Environment variables are always strings.环境变量始终是字符串。

You should assign string value to environment variable.您应该将字符串值分配给环境变量。

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

If you want to read or print the environment variable just use如果您想读取或打印环境变量,只需使用

print os.environ["DEBUSSY"]

This changes will be effective only for the current process where it was assigned, it will no change the value permanently.此更改仅对分配它的当前进程有效,不会永久更改值。 The child processes will automatically inherit the environment of the parent process.子进程会自动继承父进程的环境。

在此处输入图像描述

It should be noted that if you try to set the environment variable to a bash evaluation it won't store what you expect.应该注意的是,如果您尝试将环境变量设置为 bash 评估,它将不会存储您期望的内容。 Example:例子:

from os import environ

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

This won't evaluate it like it does in a shell, so instead of getting /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home as a path you will get the literal expression $(/usr/libexec/java_home) .这不会像在 shell 中那样评估它,因此您将获得文字表达式$(/usr/libexec/java_home) /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home $(/usr/libexec/java_home)

Make sure to evaluate it before setting the environment variable, like so:确保在设置环境变量之前对其进行评估,如下所示:

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}")

You can use the os.environ dictionary to access your environment variables.您可以使用os.environ字典来访问您的环境变量。

Now, a problem I had is that if I tried to use os.system to run a batch file that sets your environment variables (using the SET command in a **.bat* file) it would not really set them for your python environment (but for the child process that is created with the os.system function).现在,我遇到的一个问题是,如果我尝试使用os.system运行设置环境变量的批处理文件(在 **.bat* 文件中使用 SET 命令),它不会真正为你的 python 环境设置它们(但对于使用os.system函数创建的子进程)。 To actually get the variables set in the python environment, I use this script:要实际获取在 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

When you play with environment variables (add/modify/remove variables), a good practice is to restore the previous state at function completion.当您使用环境变量(添加/修改/删除变量)时,一个好的做法是在函数完成时恢复之前的状态。

You may need something like the modified_environ context manager describe in this question to restore the environment variables.您可能需要类似于此问题中描述的modified_environ上下文管理器来恢复环境变量。

Classic usage:经典用法:

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

Use setdefault function to set a new variable if the variable does not exist in the environment.如果环境中不存在变量,请使用setdefault函数设置新变量。

make sure you set the environment variable as a string, not int.确保将环境变量设置为字符串,而不是 int。 Otherwise will throw TypeError .否则会抛出TypeError

import os

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

print(os.environ["DEBUSSY"])

I wrote this little context manager which sets variables for the duration of an indented block only:我写了这个小上下文管理器,它只在缩进块的持续时间内设置变量:

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)

Example usage (with % for Windows and $ for Linux):示例用法(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)

What about the following?下面的呢?

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

<class 'int'> <类'int'>

There is good out of the box Python solution called pycrosskit .有一个很好的开箱即用的 Python 解决方案,称为pycrosskit It will create environment variables that are persistent both for Linux and Windows.它将创建对 Linux 和 Windows 都是持久的环境变量。

Usage:用法:

# 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)

If you are struggling with Flask and unittest, please remember that if you set a variable outside any method, this variable is read when you import the app.如果您在使用 Flask 和 unittest 时遇到困难,请记住,如果您在任何方法之外设置变量,则在导入应用程序时会读取此变量。 Might seem trivial, but could save some headache to someone.可能看起来微不足道,但可以避免一些人头疼。

For example, if into your Flask unittest you:例如,如果进入你的 Flask 单元测试你:

  1. import the app导入应用
  2. set the environment variable in the setUp method.setUp方法中设置环境变量。
  3. use app.test_client() to test your application使用app.test_client()测试您的应用程序

The variable into the second step will not be seen by the third step, because the variable is already read when you perform the first step.进入第二步的变量不会被第三步看到,因为当你执行第一步时,变量已经被读取了。

A neat way to manage user defined environment variables is to put all of them in a text file and load them at runtime.管理用户定义的环境变量的一种巧妙方法是将它们全部放在一个文本文件中并在运行时加载它们。 We can achieve this using the python-dotenv package, which allows us to import these variables.我们可以使用python-dotenv包来实现这一点,它允许我们导入这些变量。 This package can be installed via这个包可以通过安装

pip install python-dotenv点安装 python-dotenv

By default the module looks for a file named .env in the current directory.默认情况下,模块会在当前目录中查找名为.env的文件。 Define all your variables in this file, one per line as follows:在此文件中定义所有变量,每行一个,如下所示:

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

And then import these to your environment as follows:然后将它们导入到您的环境中,如下所示:

from dotenv import load_dotenv
load_dotenv()

You can specify the path to the file containing the defined variables as an optional argument to load_dotenv .您可以将包含已定义变量的文件的路径指定为load_dotenv的可选参数。 Subsequently, these environment variables can be accessed normally via the os module.随后,这些环境变量就可以通过os模块正常访问了。

Late answer that might help someone test fast without code changes.迟到的答案可能有助于某人在不更改代码的情况下快速测试。 Just run your app with the environment variable attached as so:只需使用附加的环境变量运行您的应用程序,如下所示:

 $ DEBUSSY=1 python3 api.py

You can pass env vars this way to any script.您可以通过这种方式将环境变量传递给任何脚本。

The environment is frozen for the code itself (not child processes) and cannot be accomplished with programmatically.代码本身(不是子进程)的环境被冻结,无法以编程方式完成。

A good solution, no matter what platform, is to wrap the call to python in a batch file.无论是什么平台,一个好的解决方案是将对 python 的调用包装在一个批处理文件中。 For example: if I were on linux, the batch file might look like例如:如果我在 linux,批处理文件可能看起来像

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM