【问题标题】:How to perform os.environ join in python?如何在 python 中执行 os.environ join?
【发布时间】:2016-03-26 04:40:16
【问题描述】:

我有一个带有默认值的 os.environ 配置(覆盖了我 90% 的需求)。我有一个特殊的应用程序框架包,例如称为SALOME,它不提供包安装到系统环境中并试图自包含,它还需要使用依赖环境变量的特殊旧技术,因此sys.pathPYTHONPATH 并不是它唯一需要的东西。当它开始在它创建的环境中调用os.environ 时,我可以获得它需要的所有变量。然后我可以序列化那个os.environ 字典。

我想知道如何将我当前运行的系统上的os.environ 与我通过序列化获得的合并应用?

【问题讨论】:

  • 你的意思是像os.environ.update(deserialized_environment)
  • @mqilson:是的,类似的。没有删除 - 只是插入和添加。
  • @DuckQueen 以及为什么 mgilson 的解决方案对您不起作用? os.environ 是一个 dict,另一个对象是 dict,dict.update 就像你解释的那样工作 - dict 数据将被来自 update() 参数的数据覆盖。不冲突的键将保持不变。
  • 是什么阻止了您在实际启动应用程序之前使用批处理或 shell 作为包装器来简单地将所需的值添加到环境中?
  • @Rogalski os.environ 不是 dict。这是一个os._Environ 实例。它提供了一个dict 接口,但是当您设置值等时,它实际上会改变与流程相关联的真实环境。

标签: python python-2.7 environment-variables


【解决方案1】:

假设您已经执行了类似以下的操作来序列化环境:

import json
import os

with open('environ.json', 'w') as f:
    json.dump(dict(**os.environ), f)

您现在可以像这样(在另一个程序中)读回这些内容

import json
import os

with open('environ.json', 'r') as f:
    os.environ.update(json.load(f))

这只会添加或更改当前环境变量以匹配保存的环境变量,但任何其他变量都将保留。

如果您只想通过添加特定变量来更新它们(例如添加额外的路径),您可以明确地这样做:

with open('environ.json', 'r') as f:
    loadedenv = json.load(f)

pathvars = ['PATH', 'PYTHONPATH']

for p in pathvars:
    os.environ[p] += ':' + loadedenv[p]

【讨论】:

  • 它会连接还是替换已经存在的字符串(例如路径)?
  • 它将用新值替换现有值。
  • @DuckQueen 要合并路径,您需要考虑如何 - 应该在现有值之前或之后添加加载的值,是否应该有合并过程?我添加了一个方法,它只是将新值添加到末尾并使用 : 分隔符。
【解决方案2】:

你可以使用包environs来实现导出os.environ字典。它具有内置的 dumper/loader 用于导出导入环境变量。

from environs import Env

env = Env()
# reading an environment variable
gh_user = env('GITHUB_USER')  # => 'sloria'
secret = env('SECRET')  # => raises error if not set

# casting
api_key = env.str('API_KEY')  # => '123abc'
date = env.date('SHIP_DATE')  # => datetime.date(1984, 6, 25)

# serialize to a dictionary of simple types (numbers and strings)
env.dump()
# { 'API_KEY': '123abc',
# 'GITHUB_USER': 'sloria',    
# 'SECRET': 'AASJI93WSJD93DWW3X0912NS2',
# 'SHIP_DATE': '1984-06-25'}}

【讨论】:

    【解决方案3】:

    如果您想为标准 python 字典不提供的字典提供多个值,则可以使用

    werkzeug.datastructures.MultiDict
    os.environ = MultiDict([('Key1', 'First Value'), ('Key1', 'Second Value')])
    

    更新的工作方式也与我在下面提到的相同。

    如果您不想在与新字典合并之前保留旧键值,则可以执行以下操作。

    由于 os.environ 是您已经在内存中拥有的字典,因此另一个字典是您正在读取的字典,因此需要将其转换为 json。我通常使用 ujson,因为它非常快。

     os.environ.update(new_dict)
    

    如果您想保存 json,您可以将其转储到文件中。

    import ujson
    
    with open('data.json', 'w') as file:
        ujson.dump(dict(**os.environ), file)
    

    如果您想读取文件并更新 os.environ 字典,则可以使用。

    with open('environ.json', 'r') as f:
        os.environ.update(ujson.load(f))
    

    【讨论】:

    • 以这种方式设置os.environ 是行不通的,因为os.environ 不“只是”一个字典——它具有实际为进程的子进程设置环境变量的方法。使用os.system(echo $Key1) 测试,你会发现它没有设置。
    猜你喜欢
    • 2015-12-11
    • 2018-10-22
    • 2023-01-09
    • 2021-02-23
    • 1970-01-01
    • 2022-08-30
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多