22👍
In your case num
is a unicode string, which does not support the f
format modifier:
>>> '{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'
You can fix the error making the conversion to float
yourself:
>>> '{0:.2f}'.format(float(u"5.0"))
'5.00'
As pointed out by mgilson when you do '{0:.2f}'.format(num)
, the format
method of the strings calls num.__format__(".2f")
. This results in an error for str
or unicode
, because they don’t know how to handle this format specifier. Note that the meaning of f
is left as an implementation for the object. For numeric types it means to convert the number to a floating point string representation, but other objects may have different conventions.
If you used the %
formatting operator the behaviour is different, because in that case %f
calls __float__
directly to obtain a floating point representation of the object.
Which means that when using %
-style formatting f
does have a specific meaning, which is to convert to a floating point string representation.
5👍
what .format() do
str.format
method calls __format__()
method of related type. That means
<type>.__format__(<value>, <spec>)
above method accepts the same type argument as first value, and accepts a suitable spec
type
as second one. Like,
str.__format__('1', 's')
int.__format__(1, 'f')
float.__format__(1.00, 'f')
str.__format__
accepts any type that is derived from str
type, like str
or unicode
. Spec value must be a valid formatter that is usable of that type. Following will raise an error
str.__format__('1', 'f')
ValueError: Unknown format code 'f' for object of type 'str'
since floating point
formatting is not a suitable format type fot string. Likewise following will raise an error too
float.__format__(1.00, 's')
ValueError: Unknown format code 's' for object of type 'float'
since float is a numeric
type and can not formatted as a string
. But following are all valid:
float.__format__(1.00, 'g')
float.__format__(1.00, 'f')
similarly following will raise an exception
float.__format__(1.00, 'd')
ValueError: Unknown format code 'd' for object of type 'float'
since formatting a float point to a decimal value will cause precision values to be lost. But formatting an int
to float
will not cause a such thing, so it is a valid conversion:
int.__format__(1, 'f')
So .format()
is limeted to specs
that is available to the related formatting type
. You must parse your value as @Bakuriu defined:
'{0:.2f}'.format(float(u"5.0"))
- [Django]-How to write a query to get find value in a json field in django
- [Django]-Django Count() in multiple annotations
- [Django]-How to decode url to path in python, django
1👍
The scenario where you are re-formatting a string (unicode or otherwise) as a float string is not very safe. You should first convert the string to a numeric representation and only if that succeeds should you format it as a string again. You are not in control of the data that comes into your program so you should be sure to validate it coming in.
If you choose to leave it as a string you can use this:
return u"{:.2f}".format(num) if num.isnumeric() else u"{}".format(num)
If you have already converted the string into a numeric format, you can adjust your formatter like this:
return u"{:.2f}".format(num) if isinstance(num, NumberTypes) else u"{}".format(num)
- [Django]-In Django what is i18n?
- [Django]-Django Tastypie Advanced Filtering: How to do complex lookups with Q objects
- [Django]-Django.template.base.TemplateSyntaxError: default requires 2 arguments, 1 provided
0👍
I’ve faced a similar problem as the OP, when num
was a numerical answer returned by one of my libraries, whose implementation detais got forgotten:
>>> 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'
I was really puzzled because num
behaved like a float but after testing @Bakuriu ‘s solution, I’ve found out it wasn’t a float:
>>> type(num)
<class 'sympy.core.numbers.Float'>
So @Bakuriu ‘s solution was right on target for my case:
>>> u'{0:.4g}'.format(float(num))
u'-4133'
Therefore, the error can be due to types that display/calculate like but aren’t really floats.
- [Django]-How to group by AND aggregate with Django
- [Django]-Django's ModelForm unique_together validation
- [Django]-Django python date time set to midnight