如果 Jinja2 没有小数值,如何四舍五入为零小数?
How to round to zero decimals if there is no decimal value with Jinja2?
我使用 jinja2 提供的(优秀)Flask framework in which I now want to display some numbers. The round filter 构建网站工作正常,除了没有小数值的情况:
{{ 1.55555|round(2) }} -> 1.56
{{ 1.5|round(2) }} -> 1.5
{{ 1.0|round(2) }} -> 1.0
{{ 1|round(2) }} -> 1.0
但我希望最后两个像 1
一样显示(没有尾随 .0
)。有人知道我如何用 jinja2 做到这一点吗?欢迎所有提示!
[编辑]
我尝试使用 trim(),但令我惊讶的是,下面的代码片段给出了 TypeError: do_trim() takes exactly 1 argument (2 given)
:
{{ 1.0|round(2)|trim('.0') }}
您可以使用 string
filter, then use str.rstrip
:
>>> import jinja2
>>> print(jinja2.Template('''
... {{ (1.55555|round(2)|string).rstrip('.0') }}
... {{ (1.5|round(2)|string).rstrip('.0') }}
... {{ (1.0|round(2)|string).rstrip('.0') }}
... {{ (1|round(2)|string).rstrip('.0') }}
... ''').render())
1.56
1.5
1
1
注意
使用 str.rstrip
,您将得到 0
的空字符串。
>>> jinja2.Template('''{{ (0|round(2)|string()).strip('.0') }}''').render()
u''
这是避免上述问题的解决方案(调用 rstrip
两次;一次使用 0
,一次使用 .
)
>>> print(jinja2.Template('''
... {{ (1.55555|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1.5|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1.0|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (0|round(2)|string).rstrip('0').rstrip('.') }}
... ''').render())
1.56
1.5
1
1
0
UPDATE 以上代码将 trim 10
变为 1
。以下代码没有问题。使用 format
filter.
>>> print(jinja2.Template('''
... {{ ("%.2f"|format(1.55555)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.5)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.5)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.0)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(0)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(10)).rstrip('0').rstrip('.') }}
... ''').render())
1.56
1.5
1.5
1
0
10
如果你打算经常使用它,我认为最好编写一个自定义过滤器以避免混乱,如下所示:
from jinja2 import filters
def myround(*args, **kw):
# Use the original round filter, to deal with the extra arguments
res = filters.do_round(*args, **kw)
# Test if the result is equivalent to an integer and
# return depending on it
ires = int(res)
return (res if res != ires else ires)
注册,大功告成。交互式解释器中的示例:
>>> from jinja2 import Environment
>>> env = Environment()
>>> env.filters['myround'] = myround
>>> env.from_string("{{ 1.4|myround(2) }}").render()
u'1.4'
>>> env.from_string("{{ 1.4|myround }}").render()
u'1'
>>> env.from_string("{{ 0.3|myround }}").render()
u'0'
更好的解决方案,避免 60.0 变成 6 和 0.0 变成空,
而不是:
(( YOURNUMBER )|string).rstrip('0')
这样做:
(( YOURNUMBER )|string )[:-2]
这将切断字符串的最后 2 个字符。由于 round(0) 总是生成一个末尾有 .0 的数字,这将很好地解决问题。
你总能做到
{{ ((1|round(2))|string).split('.')[0] }}
进程故障:
1|round(2)
-> 1.0
|string
会将输出转换为字符串,这样我们就可以使用 split()
.split('.')
将使用 .
分隔符拆分字符串 -> ["1", "0"]
- 作为
.split()
returns一个数组,[0]
之后会得到第0位的字符串-> "1"
- [可选]如果你希望结果的数据类型是数字然后在最后做
|int
我使用 jinja2 提供的(优秀)Flask framework in which I now want to display some numbers. The round filter 构建网站工作正常,除了没有小数值的情况:
{{ 1.55555|round(2) }} -> 1.56
{{ 1.5|round(2) }} -> 1.5
{{ 1.0|round(2) }} -> 1.0
{{ 1|round(2) }} -> 1.0
但我希望最后两个像 1
一样显示(没有尾随 .0
)。有人知道我如何用 jinja2 做到这一点吗?欢迎所有提示!
[编辑]
我尝试使用 trim(),但令我惊讶的是,下面的代码片段给出了 TypeError: do_trim() takes exactly 1 argument (2 given)
:
{{ 1.0|round(2)|trim('.0') }}
您可以使用 string
filter, then use str.rstrip
:
>>> import jinja2
>>> print(jinja2.Template('''
... {{ (1.55555|round(2)|string).rstrip('.0') }}
... {{ (1.5|round(2)|string).rstrip('.0') }}
... {{ (1.0|round(2)|string).rstrip('.0') }}
... {{ (1|round(2)|string).rstrip('.0') }}
... ''').render())
1.56
1.5
1
1
注意
使用 str.rstrip
,您将得到 0
的空字符串。
>>> jinja2.Template('''{{ (0|round(2)|string()).strip('.0') }}''').render()
u''
这是避免上述问题的解决方案(调用 rstrip
两次;一次使用 0
,一次使用 .
)
>>> print(jinja2.Template('''
... {{ (1.55555|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1.5|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1.0|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (0|round(2)|string).rstrip('0').rstrip('.') }}
... ''').render())
1.56
1.5
1
1
0
UPDATE 以上代码将 trim 10
变为 1
。以下代码没有问题。使用 format
filter.
>>> print(jinja2.Template('''
... {{ ("%.2f"|format(1.55555)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.5)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.5)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.0)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(0)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(10)).rstrip('0').rstrip('.') }}
... ''').render())
1.56
1.5
1.5
1
0
10
如果你打算经常使用它,我认为最好编写一个自定义过滤器以避免混乱,如下所示:
from jinja2 import filters
def myround(*args, **kw):
# Use the original round filter, to deal with the extra arguments
res = filters.do_round(*args, **kw)
# Test if the result is equivalent to an integer and
# return depending on it
ires = int(res)
return (res if res != ires else ires)
注册,大功告成。交互式解释器中的示例:
>>> from jinja2 import Environment
>>> env = Environment()
>>> env.filters['myround'] = myround
>>> env.from_string("{{ 1.4|myround(2) }}").render()
u'1.4'
>>> env.from_string("{{ 1.4|myround }}").render()
u'1'
>>> env.from_string("{{ 0.3|myround }}").render()
u'0'
更好的解决方案,避免 60.0 变成 6 和 0.0 变成空,
而不是:
(( YOURNUMBER )|string).rstrip('0')
这样做:
(( YOURNUMBER )|string )[:-2]
这将切断字符串的最后 2 个字符。由于 round(0) 总是生成一个末尾有 .0 的数字,这将很好地解决问题。
你总能做到
{{ ((1|round(2))|string).split('.')[0] }}
进程故障:
1|round(2)
->1.0
|string
会将输出转换为字符串,这样我们就可以使用split()
.split('.')
将使用.
分隔符拆分字符串 ->["1", "0"]
- 作为
.split()
returns一个数组,[0]
之后会得到第0位的字符串-> "1" - [可选]如果你希望结果的数据类型是数字然后在最后做
|int