Оставшиеся значения пустые, если не переданы в str.format

Я столкнулся с довольно простой проблемой, из-за которой я не могу придумать элегантное решение.

Я создаю строку с использованием str.format в функции, которая передается в dict замен, которые будут использоваться для формата. Я хочу создать строку и форматировать ее со значениями, если они переданы, и оставить их пустыми в противном случае.

бывший

 kwargs = {"name": "mark"} "My name is {name} and I'm really {adjective}.".format(**kwargs) 

должен вернуться

 "My name is mark and I'm really ." 

вместо того, чтобы бросать KeyError (что будет, если мы ничего не сделаем).

Смутно, я даже не могу придумать неэлегантное решение этой проблемы. Я думаю, я мог бы решить это, просто не используя str.format , но я предпочел бы использовать встроенный (который в основном делает то, что я хочу), если это возможно.

Примечание. Я заранее не знаю, какие ключи будут использоваться. Я пытаюсь потерпеть неудачу изящно, если кто-то включает ключ, но не помещает его в kwargs dict. Если бы я знал с 100% точностью, какие ключи будут подняты, я бы просто заполнил их все и покончил с этим.

6 Solutions collect form web for “Оставшиеся значения пустые, если не переданы в str.format”

Вы можете следовать рекомендации в PEP 3101 и подклассе Formatter:

 import string class BlankFormatter(string.Formatter): def __init__(self, default=''): self.default=default def get_value(self, key, args, kwds): if isinstance(key, str): return kwds.get(key, self.default) else: return string.Formatter.get_value(key, args, kwds) kwargs = {"name": "mark", "adj": "mad"} fmt=BlankFormatter() print fmt.format("My name is {name} and I'm really {adj}.", **kwargs) # My name is mark and I'm really mad. print fmt.format("My name is {name} and I'm really {adjective}.", **kwargs) # My name is mark and I'm really . по import string class BlankFormatter(string.Formatter): def __init__(self, default=''): self.default=default def get_value(self, key, args, kwds): if isinstance(key, str): return kwds.get(key, self.default) else: return string.Formatter.get_value(key, args, kwds) kwargs = {"name": "mark", "adj": "mad"} fmt=BlankFormatter() print fmt.format("My name is {name} and I'm really {adj}.", **kwargs) # My name is mark and I'm really mad. print fmt.format("My name is {name} and I'm really {adjective}.", **kwargs) # My name is mark and I'm really . 

С Python 3.2 вы можете использовать .format_map в качестве альтернативы:

 class Default(dict): def __missing__(self, key): return '{'+key+'}' kwargs = {"name": "mark"} print("My name is {name} and I'm really {adjective}.".format_map(Default(kwargs))) 

Печать:

 My name is mark and I'm really {adjective}. 

Вот один из вариантов, который использует collections.defaultdict :

 >>> from collections import defaultdict >>> kwargs = {"name": "mark"} >>> template = "My name is {0[name]} and I'm really {0[adjective]}." >>> template.format(defaultdict(str, kwargs)) "My name is mark and I'm really ." 

Обратите внимание, что мы не используем ** чтобы больше распаковать словарь в аргументы ключевых слов, а спецификатор формата использует {0[name]} и {0[adjective]} , что указывает, что мы должны выполнить ключевой поиск по первому аргументу для format() с использованием "name" и "adjective" соответственно. При использовании defaultdict отсутствующий ключ приведет к пустой строке вместо повышения KeyError.

Вы можете обновить словарь по умолчанию с помощью списка ключевых слов:

 kwargs = {"name": "mark"} defaults = {"name": "", "adjective": ""} defaults.update(kwargs) print "My name is {name} and I'm really {adjective}.".format(**defaults) 

Способ избежать ключевой ошибки состоит в том, чтобы включить в dict, но оставить его пустым:

 kwargs = {"name": "mark", "adjective": ""} "My name is {name} and I'm really {adjective}.".format(**kwargs) 

Аргументы ключевого слова предполагают, что они будут ключом в kwargs. Другой способ сделать это – позиционные аргументы:

 "My name is {0} and I'm really {1}.".format("mark") 

Печатает: «Меня зовут Марк, и я на самом деле». В то время как

 "My name is {0} and I'm really {1}.".format("mark","black") 

Печатает: «Меня зовут Марк, и я действительно черный».

Кроме того, вы можете поймать ValueError.

Для записи:

 s = "My name is {name} and I'm really {adjective}." kwargs = dict((x[1], '') for x in s._formatter_parser()) # Now we have: `kwargs = {'name':'', 'adjective':''}`. kwargs.update(name='mark') print s.format(**kwargs) # My name is mark and I'm really . 

Хотелось добавить довольно простое решение для замены любых значений по умолчанию.

 import string class SafeDict(dict): def __init__(self, missing='#', empty='', *args, **kwargs): super(SafeDict, self).__init__(*args, **kwargs) self.missing = missing self.empty = empty def __getitem__(self, item): return super(SafeDict, self).__getitem__(item) or self.empty def __missing__(self, key): return self.missing values = SafeDict(a=None, c=1}) string.Formatter().vformat('{a} {c} {d}', (), values) # ' 1 #' 
  • Python - time.clock () vs. time.time () - точность?
  • Python OSError: Нет такого файла или каталога
  • Получение случайной записи из хранилища данных Google App Engine?
  • Сортировка рук карт, которые соответствуют рангу и порядку в python
  • API облачного видения Google: «В запросе недостаточно областей проверки подлинности».
  • Различия между статическими и переменными экземпляра в python. Они даже существуют?
  • Изменить значения списка, итерации по нему в Python?
  • Python: динамический импорт «из»
  • Невозможно развернуть мое приложение в Google App Engine
  • Недопустимый аргумент OSError при использовании open () в Python
  • Каковы различные варианты социальной аутентификации в Appengine - как они сравниваются?
  • Python - лучший язык программирования в мире.