Формат строки словаря - PullRequest
0 голосов
/ 12 июня 2018

У меня есть словарная строка:

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"

Это возможно, просто загрузив строку как dict, используя json.loads(), а затем установиватрибуты по мере необходимости, но это не то, что я хочу.Я хочу отформатировать строку, чтобы я мог использовать эту строку в других файлах / модулях.1015 * 1016 Что мне здесь не хватает?Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

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
0 голосов
/ 12 июня 2018

Не пытайтесь работать со строкой 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')

Гораздо проще и безопаснее просто декодировать и перекодировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...