在 Python 中獲取、添加、覆蓋和刪除環境變量 (os.environ)

商業

可以使用 os.environ 在 Python 程序中檢索、檢查、設置(添加或覆蓋)和刪除環境變量。請注意,通過設置或刪除環境變量所做的更改僅在 Python 程序內有效。這並不意味著系統環境變量將被重寫。

此處提供以下信息。

  • os.environ
  • 獲取環境變量。
  • 設置(添加/覆蓋)環境變量
  • 刪除環境變量
  • 改變環境變量的影響
  • 通過環境變量切換進程

導入並使用 os 模塊。由於它是標準庫,因此無需額外安裝。子流程模塊也包含在標準庫中。

import os
import subprocess

操作系統環境

os.environ 的類型是 os._Environ。

print(type(os.environ))
# <class 'os._Environ'>

os._Environ 是一個 map 類型的對象,有一對鍵和值,和字典(dict 類型)有相同的方法。環境變量名是key,其值為value。

os.environ 的內容將在導入 os 模塊時加載。 os.environ 的內容即使在程序運行時通過其他方式改變了系統環境變量也不會更新。

該列表用print() 顯示。

# print(os.environ)

與字典一樣,您可以使用以下方法,或使用 in 來檢查鍵和值是否存在。

  • keys()
  • values()

鍵和值的處理與字典基本相同。下面給出了例子。

獲取環境變量。

os.environ[Environment variable name]
這將允許您獲取環境變量的值,但是如果您指定一個不存在的環境變量名稱,則會出現錯誤(KeyError)。

print(os.environ['LANG'])
# ja_JP.UTF-8

# print(os.environ['NEW_KEY'])
# KeyError: 'NEW_KEY'

如果默認值不存在,可以使用 os.environ 的 get() 方法獲取默認值。這也和字典一樣。

print(os.environ.get('LANG'))
# ja_JP.UTF-8

print(os.environ.get('NEW_KEY'))
# None

print(os.environ.get('NEW_KEY', 'default'))
# default

還提供了 os.getenv() 函數。與字典的 get() 方法一樣,如果鍵不存在,則返回默認值。如果您只想獲取和檢查環境變量的值,則此函數很有用。

print(os.getenv('LANG'))
# ja_JP.UTF-8

print(os.getenv('NEW_KEY'))
# None

print(os.getenv('NEW_KEY', 'default'))
# default

設置(添加/覆蓋)環境變量

os.environ[Environment variable name]
通過為此分配一個值,您可以設置一個環境變量。

指定新的環境變量名時,新添加環境變量,指定現有的環境變量名時,覆蓋環境變量的值。

os.environ['NEW_KEY'] = 'test'

print(os.environ['NEW_KEY'])
# test

os.environ['NEW_KEY'] = 'test2'

print(os.environ['NEW_KEY'])
# test2

請注意,分配字符串以外的任何內容都會導致錯誤(TypeError)。如果要分配數值,請將其指定為字符串。

# os.environ['NEW_KEY'] = 100
# TypeError: str expected, not int

os.environ['NEW_KEY'] = '100'

還提供了 os.putenv() 函數。但是,os.environ 的值在由 os.putenv() 設置時不會更新。因此,最好指定 os.environ 的鍵(環境變量名稱)並分配值,如上例所示。

如果支持 putenv(),則對 os.environ 中項目的賦值將自動轉換為對 putenv() 的相應調用。實際上,分配給 os.environ 中的項目是首選操作,因為直接調用 putenv() 不會更新 os.environ。
os.putenv() — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

如前所述,通過添加或覆蓋環境變量所做的更改僅在 Python 程序中有效。這並不意味著系統環境變量將被重寫。

請注意,更改該值可能會導致內存洩漏,具體取決於操作系統。

注意:在某些平台上,包括 FreeBSD 和 Mac OS X,更改environ 的值可能會導致內存洩漏。
os.putenv() — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

這是由於操作系統本身的 putenv() 規範。

Successive calls to setenv() or putenv() assigning a differently sized value to the same name will result in a memory leak. The FreeBSD seman-tics semantics for these functions (namely, that the contents of value are copied and that old values remain accessible indefinitely) make this bug unavoidable.
Mac OS X Manual Page For putenv(3)

刪除環境變量

要刪除環境變量,請使用 os.environ 的 pop() 方法或 del 語句。和字典一樣。

下面是一個 pop() 的例子。

pop() 返回被刪除的環境變量的值。默認情況下,指定一個不存在的環境變量將導致錯誤(KeyError),但如果指定第二個參數將返回該環境變量不存在的值。

print(os.environ.pop('NEW_KEY'))
# 100

# print(os.environ.pop('NEW_KEY'))
# KeyError: 'NEW_KEY'

print(os.environ.pop('NEW_KEY', None))
# None

下面是一個del的例子。

再次添加環境變量,然後刪除。如果環境變量不存在,則報錯(KeyError)。

os.environ['NEW_KEY'] = '100'

print(os.getenv('NEW_KEY'))
# 100

del os.environ['NEW_KEY']

print(os.getenv('NEW_KEY'))
# None

# del os.environ['NEW_KEY']
# KeyError: 'NEW_KEY'

還提供了 os.unsetenv() 函數。但是,與 os.putenv() 一樣,os.environ 的值在被 os.unsetenv() 刪除時不會更新。因此,最好指定 os.environ 的鍵(環境變量名稱)並將其刪除,如上例所示。

如果支持 unsetenv(),刪除 os.environ 中的一項將自動轉換為對 unsetenv() 的相應調用。實際上,刪除 os.environ 中的項目是首選操作,因為直接調用 unsetenv() 不會更新 os.environ。
os.unsetenv() — Miscellaneous operating system interfaces — Python 3.10.0 Documentation

刪除環境變量也僅在該 Python 程序中有效。它不會刪除系統環境變量。

改變環境變量的影響

正如我反複寫的,更改(設置或刪除)os.environ 環境變量不會更改系統環境變量,但它確實會影響程序中啟動的子進程。

以下代碼在 Windows 上無法正常工作,因為沒有 LANG 環境變量並且 date 命令的內容不同。

在 subprocess 模塊中調用 date 命令。

date 命令的輸出結果根據 LANG 環境變量的值而變化。

print(os.getenv('LANG'))
# ja_JP.UTF-8

print(subprocess.check_output('date', encoding='utf-8'))
# 2018年 7月12日 木曜日 20時54分13秒 JST
# 

os.environ['LANG'] = 'en_US'

print(subprocess.check_output('date', encoding='utf-8'))
# Thu Jul 12 20:54:13 JST 2018
# 

為了便於說明,我們更改了 os.environ 中的 LANG 環境變量,但是 Python 提供了 locale 模塊來控制語言環境。

通過環境變量切換進程

也可以根據環境變量的值來切換進程。

以下是根據語言設置中的 LANG 環境變量更改輸出的示例。這裡我們使用startswith()方法來判斷字符串是否以指定字符串開頭,但是如果要判斷完全匹配,可以使用“==”進行比較。

print(os.getenv('LANG'))
# en_US

if os.getenv('LANG').startswith('ja'):
    print('こんにちは')
else:
    print('Hello')
# Hello

os.environ['LANG'] = 'ja_JP'

if os.getenv('LANG').startswith('ja'):
    print('こんにちは')
else:
    print('Hello')
# こんにちは

另外,如果設置環境變量表示開發環境和生產環境,比如可以獲取這些變量的值,切換流程。

Copied title and URL