如果 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. 1|round(2) -> 1.0
  2. |string 会将输出转换为字符串,这样我们就可以使用 split()
  3. .split('.') 将使用 . 分隔符拆分字符串 -> ["1", "0"]
  4. 作为.split() returns一个数组,[0]之后会得到第0位的字符串-> "1"
  5. [可选]如果你希望结果的数据类型是数字然后在最后做|int