您的PyYAML类有一些问题:
yaml_tag
是区分大小写的,!Env
并且!ENV
是不同的标记。- 因此,根据文档,
yaml.YAMLObject
使用元类来定义自身,并具有针对这些情况的默认值to_yaml
和from_yaml
功能。但是,默认情况下,这些函数要求您对自定义标记(在这种情况下!ENV
)的参数是 mapping 。因此,要使用默认功能,您的defaults.yaml
文件必须看起来像这样(例如):
example: !ENV {env_var: "PWD", test: "test"}
然后,您的代码将保持不变,在我的情况下,
print(settings)结果为,
{'example': /home/Fred}
但您使用的
load不是
safe_load-在下面的答案中,Anthon指出这很危险,因为解析的YAML可以覆盖/读取磁盘上任何位置的数据。
你仍然可以很容易地使用你的YAML文件格式,
example: !ENVfoo-你只需要定义一个适当的
to_yaml,并
from_yaml在课堂上
EnvTag,那些能够分析并发出 标 ,如字符串“foo”变量。
所以:
import osimport yamlclass 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_loadyaml.SafeLoader.add_constructor('!ENV', EnvTag.from_yaml)# Required for safe_dumpyaml.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)添加了一个表示符。:)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)