未知格式代码' f'对于类型为'unicode'的对象

时间:2013-04-10 11:43:38

标签: python django

有人可以告诉我这段代码有什么问题......

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

它给了我以下错误:

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

我正在运行Django 1.5

谢谢

4 个答案:

答案 0 :(得分:19)

在您的情况下,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")。这会导致strunicode出错,因为他们不知道如何处理此格式说明符。请注意,f的含义保留为对象的实现。对于数字类型,它表示将数字转换为浮点字符串表示形式,但其他对象可能具有不同的约定。

如果您使用%格式化运算符,则行为会有所不同,因为在这种情况下%f会直接调用__float__来获取对象的浮点表示。 这意味着当使用%时,格式化f 具有特定含义,即转换为浮点字符串表示。

答案 1 :(得分:5)

什么.format()做

str.format方法调用相关类型的__format__()方法。这意味着

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

上面的方法接受与第一个值相同的类型参数,并接受合适的spec类型  作为第二个。像,

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

str.__format__接受来自str类型的任何类型,例如strunicode。规范值必须是可用于该类型的有效格式化程序。以下将引发错误

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

因为floating point格式不是合适的格式类型的字符串。同样,下面也会引发错误

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"))

答案 2 :(得分:1)

将字符串(unicode或其他)重新格式化为浮点字符串的方案不是很安全。您应该首先将字符串转换为数字表示形式,并且只有在成功时才应将其格式化为字符串。您无法控制程序中的数据,因此您应该确保验证它的进入。

如果您选择将其保留为字符串,则可以使用:

return u"{:.2f}".format(num) if num.isnumeric() else u"{}".format(num)

如果您已将字符串转换为数字格式,则可以像下面这样调整格式化程序:

return u"{:.2f}".format(num) if isinstance(num, NumberTypes) else u"{}".format(num)

答案 3 :(得分:0)

num是我的一个图书馆返回的数字答案时,我遇到了与OP类似的问题,其实施细则被遗忘了:

>>> 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 表现得像一个浮动但是在测试了@Bakuriu的解决方案之后,我发现它不是浮动的:

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

所以@Bakuriu的解决方案正好符合我的目标:

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

因此,错误可能是由于显示/计算类型但不是真正浮动的类型。