【问题标题】:When would os.environ['foo'] not match os.getenv('foo')?os.environ['foo'] 什么时候不匹配 os.getenv('foo')?
【发布时间】:2012-06-12 17:29:54
【问题描述】:

我有一个小型 Python 应用程序,通过 subprocess.Popen 启动,它接受一些环境变量形式的参数。我通过将环境结构传递给Popen 调用来做到这一点。然后程序通过os.getenv读取变量。

或者更确切地说,它曾经以这种方式阅读它们。在 Windows 上,它运行良好。但是在我们的 FreeBSD 服务器上,os.getenv 为我们传入的所有参数返回 None。奇怪的是 os.environ 的值很好——事实上,只需将所有 os.getenv('foo') 调用切换到 os.environ['foo']让一切在两个平台上都能正常工作。

为什么这些值不同?什么时候比较合适?

【问题讨论】:

    标签: python windows environment-variables freebsd


    【解决方案1】:

    os.environ 是在导入 os 模块时创建的,除非直接修改,否则不会反映之后发生的环境更改。然而,有趣的是,os.getenv() 实际上也没有获得最新的环境变量,至少在 CPython 中没有。你看,在 CPython 中,os.getenv() 显然只是 os.environ.get() 的一个包装器(参见 http://hg.python.org/cpython/file/6671c5039e15/Lib/os.py#l646)。因此,将os.getenv() 与所述实现一起使用的主要原因似乎是当您希望在os.environ 的键中找不到环境变量名称而不是KeyError 或其他任何东西时返回默认值扔了,你想保存几个字符。

    FreeBSD 上的实现完全有可能有一些奇怪的噱头导致其行为不同,但我不确定为什么会这样。如果可以,请在您使用的一台 FreeBSD 机器上查看 os.py 的副本。

    【讨论】:

    • 在 Windows 10 上,os.putenv('abc', '123') 不起作用,即未设置新变量。但是,os.environ['abc'] = '123' 有效,随后 os.getenv('abc') 也有效。
    • @arvindpdmn 又一查,那是因为putenv()实际上并没有把环境变量存入os.environ;相反,environ.__setitem__() 调用 putenv() 并将数据存储在本地,getenv()environ.__getitem__() 都不会真正查询环境本身,它们使用 os.environ 存储的任何内容进行操作。实现它的方式相当混乱。
    猜你喜欢
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 2015-07-30
    相关资源
    最近更新 更多