Это примерно та же проблема, что и в этом вопросе о поплавках .
Когда у вас есть значение, которое можно преобразовать в целое число, старый %d
преобразует его, а формат — нет.
class MyIntegerTenClass:
def __int__(self):
return 10
def __str__(self):
return 'ten'
ten = MyIntegerTenClass()
print '%d, %02X, %s' % (ten, ten, ten) # ok
print '{0}'.format(ten) # ok
print '{0:d}, {0:02X}'.format(ten) # ValueError: Unknown format code 'd' for object of type 'str'
Есть ли способ изменить поведение формата, не затрагивая класс форматируемого значения (без добавления метода __format__
к этому классу )?
Редактировать :Моя цель состоит в том, чтобы форматирование зависело от строки формата, но не от значения. Поэтому, если в строке формата указано «d» или «x», преобразуйте значение в int, а затем в десятичное или шестнадцатеричное представление. Если в строке формата указано «s», преобразуйте ее в строку напрямую. Как и старый %
.
На самом деле, я мог бы даже добавить метод __format__
к классу значения. Но как мне проверить в этом методе, является ли данная спецификация формата целочисленной спецификацией формата? Без повторной реализации синтаксического анализатора спецификации формата встроенного формата.
Изменить :Вот решение с __format__
и исключениями. Есть идеи получше?
class MyIntegerTenClass:
def __int__(self):
return 10
def __str__(self):
return 'ten'
def __format__(self, spec):
fmt = '{0:%s}'%spec
try:
return fmt.format(str(self))
except:
return fmt.format(int(self))
ten = MyIntegerTenClass()
print '%d, %02X, %s' % (ten, ten, ten) # ok, prints "10, 0A, ten"
print '{0:d}, {0:02X}, {0}'.format(ten) # ok, prints "10, 0A, ten"