Неизвестный формат кода 'f' для объекта типа 'unicode' - программирование
Подтвердить что ты не робот

Неизвестный формат кода 'f' для объекта типа 'unicode'

может кто-нибудь сказать мне, что не так с этим кодом...

def format_money_value(num):
    return u'{0:.2f}'.format(num)

Это дает мне следующую ошибку:

Unknown format code 'f' for object of type 'unicode'

Я запускаю Django 1.5

Спасибо

4b9b3361

Ответ 1

В вашем случае num является строкой unicode, которая не поддерживает модификатор формата f:

>>> '{0:.2f}'.format(u"5.0")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'f' for object of type 'unicode'

Вы можете исправить ошибку, сделав преобразование в float самостоятельно:

>>> '{0:.2f}'.format(float(u"5.0"))
'5.00'

Как указано в mgilson, когда вы выполняете '{0:.2f}'.format(num), метод format строк вызывает num.__format__(".2f"). Это приводит к ошибке для str или unicode, потому что они не знают, как обращаться с этим спецификатором формата. Обратите внимание, что значение f остается как реализация для объекта. Для числовых типов это означает преобразование числа в представление строки с плавающей запятой, но другие объекты могут иметь разные соглашения.

Если вы использовали оператор форматирования %, поведение отличается, потому что в этом случае %f вызывает __float__ напрямую, чтобы получить представление с плавающей точкой объекта. Это означает, что при использовании форматирования % -style f имеет определенное значение, которое должно преобразовываться в представление строки с плавающей точкой.

Ответ 2

что .format() do

str.format метод вызывает метод __format__() связанного типа. Это означает

<type>.__format__(<value>, <spec>)

выше метод принимает аргумент того же типа, что и первое значение, и принимает подходящий тип spec  как второй. Как,

str.__format__('1', 's')
int.__format__(1, 'f')
float.__format__(1.00, 'f')

str.__format__ принимает любой тип, полученный из типа str, например str или unicode. Значение Spec должно быть допустимым форматом, который можно использовать для этого типа. В результате повышается ошибка

str.__format__('1', 'f')
ValueError: Unknown format code 'f' for object of type 'str'

поскольку floating point форматирование не является подходящей строкой типа fot. Подобным образом также будет вызывать ошибку.

float.__format__(1.00, 's')
ValueError: Unknown format code 's' for object of type 'float'

поскольку float является типом numeric и не может быть отформатирован как string. Но следующие действия действительны:

float.__format__(1.00, 'g')
float.__format__(1.00, 'f')

аналогичным образом будет вызывать исключение

float.__format__(1.00, 'd')
ValueError: Unknown format code 'd' for object of type 'float'

поскольку форматирование точки с плавающей точкой до десятичного значения приведет к потере значений точности. Но форматирование int до float не приведет к такому веществу, поэтому оно является допустимым преобразованием:

int.__format__(1, 'f')

Итак, .format() лимитируется до specs, доступного для соответствующего форматирования type. Вы должны проанализировать свое значение как @Bakuriu:

'{0:.2f}'.format(float(u"5.0"))

Ответ 3

У меня возникла аналогичная проблема с OP, когда num был числовым ответом, возвращенным одной из моих библиотек, чья реализация detais забыли:

>>> num
-4132.56528214700
>>> u'{0:.4g}'.format(num)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'g' for object of type 'unicode'

Я действительно был озадачен, потому что num вел себя как float, но после тестирования решения @Bakuriu я обнаружил, что это не плавающий:

>>> type(num)
<class 'sympy.core.numbers.Float'>

Итак, решение @Bakuriu было правильным для моего случая:

>>> u'{0:.4g}'.format(float(num))
u'-4133'

Следовательно, ошибка может быть вызвана типами, которые отображают/вычисляют, но не являются плавающими.