我有一串字典,如下所示:
CREDENTIALS = "{"aaaUser": {"attributes": {"pwd": "cisco123", "name": "admin"}}}"
现在我想format
这个字符串来替换pwd
并动态name
。我尝试的是:
CREDENTIALS = "{"aaaUser": {"attributes": {"pwd": "{0}", "name": "{1}"}}}".format('password', 'username')
但这给出了以下错误:
traceback (most recent call last):
File ".ll.py", line 4, in <module>
CREDENTIALS = "{"aaaUser": {"attributes": {"pwd": "{0}", "name": "{1}"}}}".format('password', 'username')
KeyError: '"aaaUser"
只需使用json.loads()
dict
加载字符串,然后根据需要设置属性,就可以这样做,但这不是我想要的。我想格式化字符串,以便我可以在其他文件/模块中使用此字符串。 '
我在这里错过了什么?任何帮助将不胜感激。
不要尝试直接使用 JSON 字符串;对其进行解码,更新数据结构,然后重新编码:
# Use single quotes instead of escaping all the double quotes
CREDENTIALS = '{"aaaUser": {"attributes": {"pwd": "cisco123", "name": "admin"}}}'
d = json.loads(CREDENTIALS)
attributes = d["aaaUser"]["attributes"]
attributes["name"] = username
attributes["pwd"] = password
CREDENTIALS = json.dumps(d)
使用字符串格式时,您需要将字符串更改为如下所示
CREDENTIALS = '{{"aaaUser": {{"attributes": {{"pwd": "{0}", "name": "{1}"}}}}}}'
将所有文字大括号加倍,以便format
方法不会将它们误认为占位符。
但是,格式化还意味着,如果密码包含任何可能被误认为是 JSON 语法的内容(例如双引号(,则需要对密码进行预转义。
# This produces invalid JSON
NEW_CREDENTIALS = CREDENTIALS.format('new"password', 'bob')
# This produces valid JSON
NEW_CREDENTIALS = CREDENTIALS.format('new\"password', 'bob')
解码和重新编码要容易得多,也更安全。
str.format
处理用大括号括起来的文本{}
。在这里,变量CREDENTIALS
的起始字母是大括号{
它遵循str.format
规则来替换它的文本并找到紧紧关闭的大括号,因为它找不到它,而是得到另一个左大括号"{"这就是它抛出错误的原因。
调用此方法的字符串可以包含文本或由大括号 {} 分隔的替换字段
现在转义大括号并仅替换缩进的缩进,如果像两次一样封闭,则可以完成
'{{ Hey Escape }} {0}'.format(12) # O/P '{ Hey Escape } 12'
如果你逃脱了父母和祖父母{}
那么它就会起作用。
例:
'{{Escape Me {n} }}'.format(n='Yes') # {Escape Me Yes}
因此,遵循str.format
规则,我通过添加一个额外的大括号来转义用大括号括起来的父文本。
"{{"aaaUser": {{"attributes": {{"pwd": "{0}", "name": "{1}"}}}}}}".format('password', 'username')
#O/P '{"aaaUser": {"attributes": {"pwd": "password", "name": "username"}}}'
现在来到字符串格式以使其工作。还有其他方法可以做到这一点。但是,在您的情况下不建议这样做,因为您需要确保问题始终具有您提到的格式,并且永远不要弄乱其他格式,否则结果可能会发生巨大变化。
因此,这里我遵循的解决方案是使用字符串替换将格式从{0}
转换为%(0)s
,以便字符串格式可以毫无问题地工作,并且从不关心大括号。
'Hello %(0)s' % {'0': 'World'} # Hello World
所以在这里我正在使用re.sub
来替换所有出现的情况
def myReplace(obj):
found = obj.group(0)
if found:
found = found.replace('{', '%(')
found = found.replace('}', ')s')
return found
CREDENTIALS = re.sub('{d{1}}', myReplace, "{"aaaUser": {"attributes": {"pwd": "{0}", "name": "{1}"}}}"% {'0': 'password', '1': 'username'}
print CREDENTIALS # It should print desirable result