Метод str.format()
не дает вам прямого метода для обработки отсутствующих ключей или замены значений.
Вы можете добавить уровень косвенности; передайте сопоставление, которое обрабатывает отсутствующие и None
значения, и измените формат, чтобы использовать только этот аргумент:
class PlaceholderFormatValue():
def __format__(self, spec):
return '~'
def __getitem__(self, name):
# handle further nested item access
return self
class formatting_dict(dict):
def __getitem__(self, name):
value = self.get(name)
if isinstance(value, dict):
# rewrap nested dictionaries to handle missing nested keys
value = type(self)(value)
return value if value is not None else PlaceholderFormatValue()
print('{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}'.format(formatting_dict(data)))
Теперь все слоты ссылаются на позиционный аргумент 0
, который обрабатывается как словарь, но поиск по ключу всегда завершается успешно, а отсутствующие значения и None
заменяются значением-заполнителем.
Здесь PlaceholderFormatValue()
гарантирует, что независимо от того, что дает спецификация формата, значение может быть интерполировано в формат. Например, это заставляет работать {0[k]:.2f}
.
Обертывая любые значения dict
и имея доступ к элементу дескриптора PlaceholderFormatValue
, вышеизложенное также может обрабатывать отказ от предоставления вложенных ключей или целых словарей:
>>> data = {'n': 3, 'k': 3.141594, 'p': {'a': 7, 'b': 8}}
>>> del data['k']
>>> data['p']['b'] = None
>>> print('{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}'.format(formatting_dict(data)))
3, ~, 7, ~
>>> del data['p']['a']
>>> print('{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}'.format(formatting_dict(data)))
3, ~, ~, ~
>>> del data['p']
>>> print('{0[n]}, {0[k]:.2f}, {0[p][a]}, {0[p][b]}'.format(formatting_dict(data)))
3, ~, ~, ~
person
Martijn Pieters
schedule
27.11.2013