如何使用python yaml解析内部变量?

时间:2019-06-24 08:53:49

标签: python yaml

我有一个文件test.yml

---
Servers:
  Server1:
    location: "Earth"
    network: {ip: "0.0.0.0", mac: "00:00:00:00:00:00"}
    inbound: "{{ Configs.Earth.allowed_connections }}"

  Server2:
    location: "Earth"
    network: {ip: "0.0.0.1", mac: "00:00:00:00:00:02"}
    inbound: "{{ Configs.Earth.allowed_connections }}"

  Server3:
    location: "Moon"
    network: {ip: "0.0.0.2", mac: "00:00:00:00:00:02"}

  Server4:
    location: "Mars"
    network: {ip: "0.0.0.3", mac: "00:00:00:00:00:03"}
    inbound: "{{ Configs.Mars.allowed_connections }}"

Configs:
  Earth:
    allowed_connections:
      - 99.99.99.99
      - 99.99.99.98
      - 99.99.99.97

  Mars:
    allowed_connections:
      - 88.99.99.99
      - 88.99.99.98
      - 88.99.99.97

当我使用python加载yml文件时,我想解析inbound变量。有办法本地执行此操作吗?还是我需要编写一个函数来搜索包含"{{ }}"的所有变量,然后将其重置。

解决方案需要考虑变量可能位于的不同深度。

使用yaml.load加载文件没有问题,这是我在努力解决的可变分辨率

3 个答案:

答案 0 :(得分:0)

您可以在此处使用Jinja模板模块,请参见以下示例:

import yaml
from jinja2 import Environment

jsonobj = yaml.full_load(your_yaml_stream)
print jsonobj
print Environment().from_string(your_yaml_stream).render(jsonobj)

生成的输出将是:

Servers:
  Server1:
    location: "Earth"
    network: {ip: "0.0.0.0", mac: "00:00:00:00:00:00"}
    inbound: "['99.99.99.99', '99.99.99.98', '99.99.99.97']"

  Server2:
    location: "Earth"
    network: {ip: "0.0.0.1", mac: "00:00:00:00:00:02"}
    inbound: "['99.99.99.99', '99.99.99.98', '99.99.99.97']"

  Server3:
    location: "Moon"
    network: {ip: "0.0.0.2", mac: "00:00:00:00:00:02"}

  Server4:
    location: "Mars"
    network: {ip: "0.0.0.3", mac: "00:00:00:00:00:03"}
    inbound: "['88.99.99.99', '88.99.99.98', '88.99.99.97']"

Configs:
  Earth:
    allowed_connections:
      - 99.99.99.99
      - 99.99.99.98
      - 99.99.99.97

  Mars:
    allowed_connections:
      - 88.99.99.99
      - 88.99.99.98
      - 88.99.99.97

答案 1 :(得分:0)

您可以将正则表达式用于功能: ("(.*?)") 它将找到所有带引号的单词。您只需要检查字符串中是否有“ Configs.Mars.allowed_connections”即可。

Check this exemple of regex

答案 2 :(得分:-1)

您可以为此使用锚点/别名。

例如,您的示例的简化版本

>>> import yaml
>>> doc = """
Configs: 
  Mars: 
    allowed_connections: &mars # Mark this as an anchor
      - 88.99.99.99 
      - 88.99.99.98 
      - 88.99.99.97 
Servers: 
  Server: 
    location: "Mars" 
    network: {ip: "0.0.0.3", mac: "00:00:00:00:00:03"} 
    inbound: *mars  # references the anchor here
"""
>>> from pprint import pprint # just for formatting
>>> pprint(yaml.load(doc))
{'Configs': {'Mars': {'allowed_connections': ['88.99.99.99',
                                              '88.99.99.98',
                                              '88.99.99.97']}},
 'Servers': {'Server': {'inbound': ['88.99.99.99',
                                    '88.99.99.98',
                                    '88.99.99.97'],
                        'location': 'Mars',
                        'network': {'ip': '0.0.0.3',
                                    'mac': '00:00:00:00:00:03'}}}}

请注意,配置部分必须位于服务器部分之前,以便可以对其进行引用。

更多示例here