Включение отформатированного итерации как части большей форматированной строки

При написании класса недавно я сначала включил метод __repr__ в следующих строках:

 return "{}({!r}, {!r}, {!r})".format( self.__class__.__name__, self.arg1, self.arg2, self.arg3) 

Повторение фрагмента «{! R}», похоже, ошибочно, и было бы утомительно поддерживать, если я когда-либо добавлю больше аргументов в этот класс. Тем не менее, более надежные альтернативы, которые произошли со мной, не собираются выигрывать какие-либо призы за элегантность.

Форматирование строкой формата:

 fmt = "{}(%s)" % ", ".join(["{!r}"]*3) return fmt.format(self.__class__.__name__, self.arg1, self.arg2, self.arg3) 

Форматирование аргументов отдельно с помощью str.join :

 args = ", ".join(map(repr, [self.arg1, self.arg2, self.arg3])) return "{}({})".format(self.__class__.__name__, args) 

В настоящее время я реализовал класс, используя последний пример, но меня интересуют предложения по альтернативным подходам (поскольку я не очень доволен любым из вышеперечисленных вариантов).

Обновление: Вдохновленный ответом Неда, я добавил следующую вспомогательную функцию в вспомогательный модуль:

 def format_iter(iterable, fmt='{!r}', sep=', '): return sep.join(fmt.format(x) for x in iterable) >>> format_iter(range(10)) '0, 1, 2, 3, 4, 5, 6, 7, 8, 9' >>> format_iter(range(10), sep='|') '0|1|2|3|4|5|6|7|8|9' >>> format_iter(range(10), fmt='{:04b}', sep='|') '0000|0001|0010|0011|0100|0101|0110|0111|1000|1001' >>> format_iter(range(10), fmt='{0.real}+{0.imag}j') '0+0j, 1+0j, 2+0j, 3+0j, 4+0j, 5+0j, 6+0j, 7+0j, 8+0j, 9+0j' 

Update2: Я закончил добавление второй функции утилиты, почти такой же, как в ответе agf:

 def call_repr(name, *args): return "{}({})".format(name, format_iter(args)) 

Таким образом, первоначально оскорбительная функция __repr__ теперь выглядит так:

 def __repr__(self): return call_repr(self.__class__.__name__, self.arg1, self.arg2) 

(Да, один из исходных аргументов конструктора ушел раньше сегодня.)

3 Solutions collect form web for “Включение отформатированного итерации как части большей форматированной строки”

Если это образец, который вы собираетесь повторить, я бы, вероятно, использовал:

 # This is a static method or module-level function def argrepr(name, *args): return '{}({})'.format(name, ', '.join(repr(arg) for arg in args)) def __repr__(self): return argrepr(self.__name__, self.arg1, self.arg2, self.arg3) 

или

 # This is a static method or module-level function def argrepr(*args): return '(' + ', '.join(repr(arg) for arg in args) + ')' def __repr__(self): return repr(self.__name__) + argrepr(self.arg1, self.arg2, self.arg3) 

Моя склонность была бы, если вам не нравится код, скрыть его в функции:

 def repr_all(*args): return ", ".join(repr(a) for a in args) def __repr__(self): args = repr_all(self.arg1, self.arg2, self.arg3) return "{}({})".format(self.__class__.__name__, args) 

Я могу сделать это так:

 def __repr__(self): return "{0}({1})".format( type(self).__name__, ", ".join(repr(arg) for arg in (self.arg1, self.arg2, self.arg3))) 

или:

 _init_getter = operator.attrgetter('arg1', 'arg2', 'arg3') def __repr__(self): return "{0}({1})".format( type(self).__name__, ", ".join(repr(arg) for arg in self._init_getter(self))) 
  • Проверка того, имеет ли строка повторяющиеся символы
  • python random.setstate (), seed () - есть ли гарантия одинаковых результатов в реализациях?
  • как правильно перетасовать список в python
  • Какое наибольшее число может обрабатывать десятичный класс?
  • Что означает «выбор должен быть последовательным для всех потребителей»?
  • В чем разница между одиночными, двойными и тройными кавычками в python?
  • next () не играет хорошо с любым / все в python
  • как я могу упаковать coroutine как нормальную функцию в цикле событий?
  • Python - лучший язык программирования в мире.