在Python中获取、添加、覆盖和删除环境变量(os.environ)

商业

环境变量可以在Python程序中使用os.environ进行检索、检查、设置(添加或覆盖)和删除。注意,通过设置或删除环境变量所做的改变只在Python程序中有效。这并不意味着系统环境变量会被重写。

这里提供了以下信息。

  • os.environ
  • 获取环境变量。
  • 设置(add/overwrite)环境变量
  • 移除环境变量
  • 改变环境变量的影响
  • 通过环境变量切换进程

导入并使用os模块。由于它是一个标准库,不需要额外的安装。subprocess模块也包含在标准库中。

import os
import subprocess

环境

os.environ的类型是os._Environ。

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

os._Environ 是一个有一对 key 和 value 的 map 类型对象,它的方法与 dictionary(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

设置(add/overwrite)环境变量

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 语句。与 dictionary 相同。

下面是一个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

以下是德尔的一个例子。

环境变量被再次添加,然后被删除。如果环境变量不存在,会出现错误(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命令的内容也不同。

在子进程模块中调用日期命令。

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 模块来控制 locale。

通过环境变量切换进程

也可以根据环境变量的值来切换进程。

下面是一个根据语言设置中的LANG环境变量改变输出的例子。这里我们使用startwith()方法来确定字符串是否以指定的字符串开始,但如果你想确定完全匹配,你可以使用”==”来比较。

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