环境变量可以在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')
# こんにちは
此外,如果环境变量被设置为指示开发环境和生产环境,例如,你可以获得这些变量的值并切换进程。