簡體   English   中英

Python如何設置環境變量?

[英]How to set environment variables in Python?

我需要在 Python 腳本中設置一些環境變量,我希望從 Python 調用的所有其他腳本都能看到環境變量的設置。

如果我做,

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”代替“未設置”

所以,把這一切放在一起

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 字典,因此可以執行所有常見的字典操作。 除了其他答案中提到的getset操作之外,我們還可以簡單地檢查一個鍵是否存在。 鍵和值應存儲為字符串

蟒蛇 3

對於 python 3,字典使用in關鍵字而不是has_key

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

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

在使用此方法之前,請瀏覽評論部分

我一直在嘗試添加環境變量。 我的目標是將一些用戶信息存儲到系統變量中,以便我可以將這些變量用於未來的解決方案,作為配置文件的替代方案。 但是,下面代碼中描述的方法根本沒有幫助我。

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

我希望這對你們中的一些人有所幫助。

如果我做 os.environ["DEBUSSY"] = 1,它會抱怨說 1 必須是字符串。

然后做

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

我還想知道一旦我設置了它,如何在 python 中讀取環境變量(在腳本的后面部分)。

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

some_value = os.environ["DEBUSSY"]

設置變量:

item 使用 key 的賦值方法:

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'作為返回值

方法二:

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

方法三:

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

方法四:

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

os.environ["DEBUSSY"] = '1'怎么樣? 環境變量始終是字符串。

您應該將字符串值分配給環境變量。

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

如果您想讀取或打印環境變量,只需使用

print os.environ["DEBUSSY"]

此更改僅對分配它的當前進程有效,不會永久更改值。 子進程會自動繼承父進程的環境。

在此處輸入圖像描述

應該注意的是,如果您嘗試將環境變量設置為 bash 評估,它將不會存儲您期望的內容。 例子:

from os import environ

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

這不會像在 shell 中那樣評估它,因此您將獲得文字表達式$(/usr/libexec/java_home) /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}")

您可以使用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

當您使用環境變量(添加/修改/刪除變量)時,一個好的做法是在函數完成時恢復之前的狀態。

您可能需要類似於此問題中描述的modified_environ上下文管理器來恢復環境變量。

經典用法:

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

如果環境中不存在變量,請使用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"])

我寫了這個小上下文管理器,它只在縮進塊的持續時間內設置變量:

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)

下面的呢?

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

<類'int'>

有一個很好的開箱即用的 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)

如果您在使用 Flask 和 unittest 時遇到困難,請記住,如果您在任何方法之外設置變量,則在導入應用程序時會讀取此變量。 可能看起來微不足道,但可以避免一些人頭疼。

例如,如果進入你的 Flask 單元測試你:

  1. 導入應用
  2. setUp方法中設置環境變量。
  3. 使用app.test_client()測試您的應用程序

進入第二步的變量不會被第三步看到,因為當你執行第一步時,變量已經被讀取了。

管理用戶定義的環境變量的一種巧妙方法是將它們全部放在一個文本文件中並在運行時加載它們。 我們可以使用python-dotenv包來實現這一點,它允許我們導入這些變量。 這個包可以通過安裝

點安裝 python-dotenv

默認情況下,模塊會在當前目錄中查找名為.env的文件。 在此文件中定義所有變量,每行一個,如下所示:

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

然后將它們導入到您的環境中,如下所示:

from dotenv import load_dotenv
load_dotenv()

您可以將包含已定義變量的文件的路徑指定為load_dotenv的可選參數。 隨后,這些環境變量就可以通過os模塊正常訪問了。

遲到的答案可能有助於某人在不更改代碼的情況下快速測試。 只需使用附加的環境變量運行您的應用程序,如下所示:

 $ DEBUSSY=1 python3 api.py

您可以通過這種方式將環境變量傳遞給任何腳本。

代碼本身(不是子進程)的環境被凍結,無法以編程方式完成。

無論是什么平台,一個好的解決方案是將對 python 的調用包裝在一個批處理文件中。 例如:如果我在 linux,批處理文件可能看起來像

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM