Оставшиеся значения пустые, если не переданы в 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
  • заменить пустую строку (ы) в кортеже
  • Загрузка сторонних библиотек Python
  • нахождение max в python в соответствии с определенным пользовательским критерием
  • Как преобразовать шестнадцатеричную строку в шестнадцатеричный номер?
  • Проблема с отступом Python?
  • Как загрузить данные навалом в хранилище приложений? Старые методы не работают
  • Python - лучший язык программирования в мире.