【问题标题】:Advanced Python string formatting with custom placeholders? [duplicate]带有自定义占位符的高级 Python 字符串格式? [复制]
【发布时间】:2016-03-16 20:37:07
【问题描述】:

我在 Python 变量中有以下 HTML 模板:

template = """
    <script>
        function work()
        {
            alert('bla');
        }
    </script>

    Success rate is {value:.2%} percent.
"""

我想用一些具有适当格式的十进制数替换{value:.2%}。由于我的模板可能包含大量 JavaScript 代码,因此我想避免使用 {{}} 转义大括号,因此不能直接使用 template.format(...)

使用Template(template).substitute(...) 似乎也是不可能的,因为我想要value 的高级格式。

我可以用相应的%(value)... 语法替换{value:.2%},然后使用template % ...。但我不喜欢这种语法,因为实际模板中的大多数变量不需要高级格式,所以我想保持占位符语法简单。

所以我的问题是,是否可以在模板中使用自定义占位符,以便在必要时进行高级格式化,即只需 {{value}}[[value]] 以及 {{value:.2%}}[[value:.2%]]

编辑:最后,我想避免.format(...) 在模板包含占位符时产生的错误,例如{{dont_want_this_substituted}},传递的字典不包含值。也就是说,我只想替换某些占位符,而不是模板中出现的所有占位符。

编辑2:为了实现我想要的,我可以先用正则表达式抓取所有占位符,然后格式化它们的内容,最后在模板中进行替换。但我想知道是否存在更简单的解决方案。

编辑 3: 建议我拆分模板以避免format() 出现问题。但是,我想避免这种情况,因为模板实际上来自文件。

【问题讨论】:

  • 无法预先格式化您的值吗?
  • @CodyGuldner 我可以,但我想在模板本身中指定格式。我可以使用正则表达式获取所有占位符,然后通过首先格式化它们的内容来替换它们,但我想知道是否存在更简单的解决方案。我将编辑问题以澄清这一点。
  • 为什么不能有多个文件?或者只是单独存储您的模板。

标签: python string-formatting string-interpolation


【解决方案1】:

忘记正则表达式和预处理。您应该分解模板,以便可变部分与&lt;script&gt; 部分不在同一个字符串中。

head = """
    <script>
        function work()
        {
            alert('bla');
        }
    </script>
"""


template = """
    {head}

    Success rate is {value:.2%} percent.
"""

最后,我想避免 .format(...) 在模板包含占位符时产生的错误,例如 {{dont_want_this_submitted}},传递的字典不包含值。也就是说,我只想替换某些占位符,而不是模板中出现的所有占位符。

这可能很hacky,但你可以使用collections.defaultdict,如图in this answer。该答案的代码示例(已修改)。

from collections import defaultdict

my_csv = '{optional[first]},{optional[middle]},{optional[last]}'
print( my_csv.format( optional=defaultdict(str, first='John', last='Doe') ) )

【讨论】:

  • 我想避免拆分模板,因为它来自文件。我将更新问题以澄清这一点。
【解决方案2】:

只需预处理您的模板。例如,如果您希望 [[...]] 成为您的模板标记并保留单个 {} 字符:

template = """
    <script>
        function work()
        {
            alert('bla');
        }
    </script>

    Success rate is [[value:.2%]] percent.
"""

result = template.replace("{", "{{").replace("}", "}}").replace("[[", "{").replace("]]", "}").format(value=0.8675309)

尝试使用不同数量的花括号来完成这一切是很棘手的,所以我肯定会使用其他一些字符。不过要小心,像 [[]] 这样的事情可能会合理地出现在合法的 JavaScript 代码中。可能会更好地使用一些永远无法使用的东西。

【讨论】:

  • 谢谢,这确实是一个选项。虽然如果我想使用 {{...}} 作为占位符会有点棘手,即可能需要一些正则表达式替换。想知道是否有更好的方法?我还编辑了原始问题,要求仅替换某些占位符。
  • 在这种情况下,您将需要编写自己的模板引擎。
  • * 另见: stackoverflow.com/a/41231617/42223 ;;使用自定义类扩展 str.format() 方法的解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多