字符串格式 JSON 字符串给出 KeyError
Posted
技术标签:
【中文标题】字符串格式 JSON 字符串给出 KeyError【英文标题】:String format a JSON string gives KeyError 【发布时间】:2013-04-27 17:35:39 【问题描述】:为什么这段代码会给出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"'
【问题讨论】:
【参考方案1】:正如 Tudor 在 comment 中提到的另一个答案,Template 类是最适合我的解决方案。我正在处理嵌套字典或字典列表,并且处理它们并不那么简单。
虽然解决方案很简单,但使用模板。
我从一个转换成字符串的字典开始。然后,我将所有 实例替换为
$
,这是用于替换占位符的模板标识符。
让它工作的关键是使用模板方法safe_substitute
。它将替换所有有效的占位符,如$user_id
,但忽略任何属于字典结构的无效占位符,如$'name': 'John', ...
。
替换完成后,我删除所有剩余的 $
并将字符串转换回字典。
在下面的代码中,resolve_placeholders
返回一个字典,其中每个键都与有效负载字符串中的占位符匹配,值被模板类替换。
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)
【讨论】:
我使用了这种方法,因为它在使用 RegEx 后非常优雅,并且使用了一个否定的lookbehind 允许我的 JSON 模板仍然使用$
来清楚地指示模板标签。所以你的payload.replace( ... )
变成re.sub(r"(?<!\$)()", '$', payload)
只替换
并忽略所有出现的$
。最后一步对于.replace( ...)
来说是可以的,但为了完整起见,我使用了re.sub(r"(\$\)", '', payload)
【参考方案2】:
继续Martijn Pieters 回答和评论:
根据 MArtijn 的评论,转义不是占位符的 .. 对是使用嵌套字典的方式。我没有成功,所以我建议以下方法。
对于嵌套字典,我尝试在嵌套字典的任何 和 上加倍。
a='"names":"a":"name"'
a.format(name=123) 输出:
输出:'"names":"a":"123"'
但这使得使用 format 来更改 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)
【讨论】:
也许string.Template 可能会有所帮助。【参考方案3】:你需要把外大括号加倍;否则 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('File': 'My_file_name',
... 'Success': True,
... 'ErrorMessage': '',
... 'LogIdentifier': '123')
"LogIdentifier": "123", "ErrorMessage": "", "Success": true, "File": "My_file_name"
注意输出中的小写 true
,这是 JSON 标准所要求的。
【讨论】:
如果我能给这个答案 10 票,我会的。谢谢 为了清楚起见,我将添加此评论作为答案。请注意,对于嵌套字典,您需要在嵌套字典的任何 和 上加倍。 @RaamEE:你需要转义 all..
不是占位符的对。以上是关于字符串格式 JSON 字符串给出 KeyError的主要内容,如果未能解决你的问题,请参考以下文章
Pandas json_normalize 返回 KeyError