os.environ.setdefault() 和 os.environ.putenv() 有什么区别

what is the difference between os.environ.setdefault() vs os.environ.putenv()

据我了解,两者都应该设置环境变量。但是在 django 的 manage.py 文件中切换这两者会导致不同的结果。

>>> help(os.environ.putenv)
putenv(name, value, /)                                       
    Change or add an environment variable

如果我编辑 manage.py 文件并将 os.environ.setdefault 更改为 os.environ.putenv,我会得到以下内容:

问题:为什么os.environ.setdefault在这种情况下有效,而os.environ.putenv却无效。

主要区别在于 os.environ.setdefaultos.environ 视为 python dict,而 os.putenvos.environ.putenv 会更改影响以 os.system()os.popen()os.fork()os.execv() 开头的子进程的环境。 os.putenv 的文档对 os.environos.putenv 之间的关系做了以下说明:

Assignments to items in os.environ are automatically translated into corresponding calls to putenv(); however, calls to putenv() don’t update os.environ, so it is actually preferable to assign to items of os.environ.

根据上面的说法,用os.putenv更新环境变量不一定会更新os.environ字典。因此,归结为如何使用相关环境变量。在 Django 的情况下,使用以下代码行在 django/config/__init__.py 文件中访问有问题的环境变量:

settings_module = os.environ.get(ENVIRONMENT_VARIABLE)

显然,这一行将 os.environ 视为字典。由于使用 os.putenv 所做的更改不会影响此 os.environ 字典,因此 django 无法找到设置模块(即 settings_module 变量等于 None).

总而言之,如果要更新环境变量,使用os.environ['VARIABLE'] = 'VALUE'os.environ.setdefault更为全面。因为,如上所述,更新 os.environ 既更新了字典,也调用了 os.putenv.