gpt4 book ai didi

python - 在 PyYAML 中创建自定义标签

转载 作者:太空宇宙 更新时间:2023-11-03 12:55:45 27 4
gpt4 key购买 nike

我正在尝试使用 Python 的 PyYAML 创建一个自定义标签,允许我使用我的 YAML 检索环境变量。

import os
import yaml

class EnvTag(yaml.YAMLObject):
yaml_tag = u'!Env'

def __init__(self, env_var):
self.env_var = env_var

def __repr__(self):
return os.environ.get(self.env_var)

settings_file = open('conf/defaults.yaml', 'r')
settings = yaml.load(settings_file)

defaults.yaml 的内部很简单:

example: !ENV foo

我不断收到的错误:

yaml.constructor.ConstructorError: 
could not determine a constructor for the tag '!ENV' in
"defaults.yaml", line 1, column 10

我也计划拥有多个自定义标签(假设我可以让这个标签正常工作)

最佳答案

您的 PyYAML 类有一些问题:

  1. yaml_tag 区分大小写,所以 !Env!ENV 是不同的标签。
  2. 因此,根据文档,yaml.YAMLObject 使用元类来定义自身,并具有默认的 to_yamlfrom_yaml 函数那些案件。但是,默认情况下,这些函数要求您对自定义标记(在本例中为 !ENV)的参数是一个映射。因此,要使用默认函数,您的 defaults.yaml 文件必须如下所示(仅作为示例):

example: !ENV {env_var: "PWD", test: "test"}

然后您的代码将保持不变,在我的例子中,print(settings) 现在的结果是 {'example':/home/Fred} 但是您'重新使用 load 而不是 safe_load —— 在他们下面的回答中,Anthon 指出这是危险的,因为解析的 YAML 可以覆盖/读取磁盘上任何位置的数据。

您仍然可以轻松地使用您的 YAML 文件格式,例如:!ENV foo——您只需要定义一个合适的 to_yamlfrom_yaml在类 EnvTag 中,可以解析和发出 标量 变量,例如字符串“foo”。

所以:

import os
import yaml

class EnvTag(yaml.YAMLObject):
yaml_tag = u'!ENV'

def __init__(self, env_var):
self.env_var = env_var

def __repr__(self):
v = os.environ.get(self.env_var) or ''
return 'EnvTag({}, contains={})'.format(self.env_var, v)

@classmethod
def from_yaml(cls, loader, node):
return EnvTag(node.value)

@classmethod
def to_yaml(cls, dumper, data):
return dumper.represent_scalar(cls.yaml_tag, data.env_var)

# Required for safe_load
yaml.SafeLoader.add_constructor('!ENV', EnvTag.from_yaml)
# Required for safe_dump
yaml.SafeDumper.add_multi_representer(EnvTag, EnvTag.to_yaml)

settings_file = open('defaults.yaml', 'r')

settings = yaml.safe_load(settings_file)
print(settings)

s = yaml.safe_dump(settings)
print(s)

当这个程序运行时,它输出:

{'example': EnvTag(foo, contains=)}
{example: !ENV 'foo'}

此代码的好处是 (1) 使用原始的 pyyaml,因此无需额外安装,以及 (2) 添加代表。 :)

关于python - 在 PyYAML 中创建自定义标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43058050/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com