python-3.x 如何在json格式的字符串中使用str.format?

7hiiyaii  于 2023-04-22  发布在  Python
关注(0)|答案(2)|浏览(99)

Python版本3.5
我尝试使用json作为格式进行API调用来配置设备。一些json会根据所需的命名而变化,因此我需要调用字符串中的变量。我可以使用旧样式%s... % (variable)完成此操作,但不能使用新样式{}... .format(variable)
失败EX:

(Testing with {"fvAp":{"attributes":{"name":(variable)}}})

a = "\"app-name\""

app_config = ''' { "fvAp": { "attributes": { "name": {} }, "children": [ { "fvAEPg": { "attributes": { "name": "app" }, "children": [ { "fvRsBd": { "attributes": { "tnFvBDName": "default" }, } } ] } }, { "fvAEPg": { "attributes": { "name": "db" }, "children": [ { "fvRsBd": { "attributes": { "tnFvBDName": "default" }, } } ] } } ] } } '''.format(a)

print(app_config)

追溯(最近一次调用):File“C:/...,line 49,in '''.format('a ')KeyError:'\n“fvAp”'
工作EX:

a = "\"app-name\""

app_config = ''' { "fvAp": { "attributes": { "name": %s }, "children": [ { "fvAEPg": { "attributes": { "name": "app" }, "children": [ { "fvRsBd": { "attributes": { "tnFvBDName": "default" }, } } ] } }, { "fvAEPg": { "attributes": { "name": "db" }, "children": [ { "fvRsBd": { "attributes": { "tnFvBDName": "default" }, } } ] } } ] } } ''' % a

print(app_config)

如何使用str.format方法来实现?

icnyk63a

icnyk63a1#

Format String Syntax section说道:
格式字符串包含由花括号{}包围的“替换字段”。任何不包含在花括号中的内容都被认为是文本,它被原封不动地复制到输出中。如果你需要在文本中包含一个花括号字符,它可以通过加倍来转义:{{}}
因此,如果你想使用.format方法,你需要转义模板字符串中的所有JSON花括号:

>>> '{{"fvAp": {{"attributes": {{"name": {}}}}}}}'.format('"app-name"')
'{"fvAp": {"attributes": {"name": "app-name"}}}'

看起来真的很糟
使用string.Template有一个更好的方法:

>>> from string import Template
>>> t = Template('{"fvAp": {"attributes": {"name": "${name}"}}')
>>> t.substitute(name='StackOverflow')
'{"fvAp": {"attributes": {"name": "StackOverflow"}}'

尽管我建议完全放弃以这种方式生成配置的想法,而是使用工厂函数和json.dumps

>>> import json
>>> def make_config(name):
...     return {'fvAp': {'attributes': {'name': name}}}
>>> app_config = make_config('StackOverflow')
>>> json.dumps(app_config)
'{"fvAp": {"attributes": {"name": "StackOverflow"}}}'
hwazgwia

hwazgwia2#

看起来你试图用运行时对应的值替换json文件中的动态值。在这种情况下,你可以使用PLACEHOLDER。在你想用动态值替换它们的地方,使用PLACEHOLDER值来构建你的json。
例如:

{
    "services": [{
            "name": "service_a",
            "config": {
                "dynamic_value_1": "PLACEHOLDER",
                "dynamic_value_2": "PLACEHOLDER"
            }
        },
        {
            "name": "service_a",
            "config": {
                "dynamic_value_1": "PLACEHOLDER",
                "dynamic_value_2": "PLACEHOLDER"
            }
        }
    ]
}

然后,您可以读取json文件,并通过传递要替换的值的字典来执行更新。

def dynamic_values() -> Dict:
        """
        Provides a map of placeholder values with their dynamic counterparts
        """
        return {
            "service_a": {
                "dynamic_value_1": service_a_method_1(),
                "dynamic_value_2": service_a_method_2(),
            },
            "service_b": {
                "dynamic_value_1": service_b_method_1(),
                "dynamic_value_2": service_b_method_1(),
            },
        }

def load_dynamic_values(dynamic_values) -> List:
        """
        Overrides placeholder values in json file with dynamic values at runtime
        """
        with open(file_name, "r") as f:
            data = json.load(f)

        services = data["services"]
        for s in services:
            override = dynamic_values.get(s["name"], None)
            if override:
                s["config"].update(override)
        return services

相关问题