字符串格式JSON字符串给出KeyError

时间:2013-05-03 10:30:18

标签: python json string format

为什么此代码会提供KeyError

output_format = """
{ 
    "File": "{filename}", 
    "Success": {success}, 
    "ErrorMessage": "{error_msg}", 
    "LogIdentifier": "{log_identifier}" 
}
"""

print output_format.format(filename='My_file_name',
                           success=True,
                           error_msg='',
                           log_identifier='123')

错误讯息:

KeyError: ' "File"'

3 个答案:

答案 0 :(得分:45)

你需要加倍外括号;否则Python认为{ "File"..也是一个参考:

output_format = '{{ "File": "{filename}", "Success": {success}, "ErrorMessage": "{error_msg}", "LogIdentifier": "{log_identifier}" }}'

结果:

>>> print output_format.format(filename='My_file_name',
...                            success=True,
...                            error_msg='',
...                            log_identifier='123')
{ "File": "My_file_name", "Success": True, "ErrorMessage": "", "LogIdentifier": "123" }

如果不经意地,您正在制作JSON输出,那么最好使用json module

>>> import json
>>> print json.dumps(dict(File='My_file_name',
...                            Success=True,
...                            ErrorMessage='',
...                            LogIdentifier='123'))
{"LogIdentifier": "123", "ErrorMessage": "", "Success": true, "File": "My_file_name"}

请注意输出中的小写 true,符合JSON标准的要求。

答案 1 :(得分:2)

正如Tudor在另一个答案的comment中所提到的,Template类是最适合我的解决方案。我正在处理嵌套字典或字典列表,但处理起来并不那么简单。

使用模板虽然解决方案非常简单。

我首先将字典转换为字符串。然后,我将{的所有实例替换为${,这是模板标识符,用于替换占位符。

使此功能生效的关键是使用模板方法safe_substitute。它将替换${user_id}之类的所有有效占位符,但忽略诸如${'name': 'John', ...之类的字典结构中的所有无效占位符。

替换完成后,我删除所有剩余的$并将字符串转换回字典。

在下面的代码中,resolve_placeholders返回一个字典,其中每个键与有效负载字符串中的占位符匹配,并且该值由Template类替代。

from string import Template
.
.
.
payload = json.dumps(payload)
payload = payload.replace('{', '${')
replace_values = self.resolve_placeholders(payload)
if replace_values:
    string_template = Template(payload)
    payload = string_template.safe_substitute(replace_values)
payload = payload.replace('${', '{')
payload = json.loads(payload)

答案 2 :(得分:0)

扩展Martijn Pieters的答案和评论:

  1. 根据MArtijn的评论,转义不是占位符的{..}对是它们与嵌套字典一起使用的方式。我没有成功执行此操作,因此建议使用以下方法。

  2. 对于嵌套字典,我尝试将任何{和}嵌套字典加倍。

  

a ='{{“名称”:{{“ a”:“ {名称}”}}}}'

     

a.format(name = 123)输出:

     

输出:'{“名称”:{“ a”:“ 123”}}'

但是,这使得使用格式更改json字符串中的值(一种过于复杂的方法)成为可能,因此我在format命令上使用了一种扭曲。 我将$ {param_name}替换为json字符串。例如:

我的预定义JSON如下所示:

   my_json_dict = {
        'parameter': [
            {
                'name': 'product',
                'value': '${product}'
            },
            {
                'name': 'suites',
                'value': '${suites}'
            },
            {
                'name': 'markers',
                'value': '${markers}'
            }
        ]
    }

我提供这本词典作为替换值而不是参数

    parameters = {
        'product': 'spam',
        'suites': 'ham',
        'markers': 'eggs'
    }

并使用此代码进行替换

json_str = json.dumps(my_json_dict)
for parameter_name, parameter_value in parameters.iteritems():
        parameter_name = '${'+parameter_name+'}'
        json_str = json_str.replace(parameter_name, parameter_value)

json_dict = json.loads(json_str)