Advanced Python string formatting with custom placeholders? [duplicate]

霸气de小男生 提交于 2019-12-11 01:26:05

问题


I have the following HTML template in a Python variable:

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

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

I want to substitute {value:.2%} with some decimal number with the appropriate formatting. Since my template may contain a lot of JavaScript code, I want to avoid escaping the curly braces with {{ and }}, so using template.format(...) directly is not an option.

Using Template(template).substitute(...) also seems impossible because I want advanced formatting for value.

I could probably replace {value:.2%} with a corresponding %(value)... syntax and then use template % .... But I'm not a fan of this syntax because most of the variables in a real-world template won't need advanced formatting, so I want to keep the placeholder syntax simple.

So my question is, is it possible to use custom placeholders in the template that would allow for advanced formatting when necessary, i.e. to have simply {{value}} or [[value]] but also {{value:.2%}} or [[value:.2%]] ?

Edit: Finally, I want to avoid errors that .format(...) would produce when the template contains placeholders, such as {{dont_want_this_substituted}}, for which the passed dictionary doesn't contain a value. That is, I want to only substitute only certain placeholders, not all that appear in the template.

Edit 2: To achieve what I want, I can grab all placeholders with a regular expression first, then format their contents and finally make the replacement in the template. But I wonder if an easier solution exists.

Edit 3: It was suggested that I split the template to avoid issues with format(). I would like to avoid this, however, because the template actually comes from a file.


回答1:


Simply preprocess your template. For example, if you want [[...]] to be your template markers and leave single { and } characters alone:

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

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

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

Trying to do it all with varying numbers of curly brackets is tricksy, so I would definitely use some other characters. Careful, though, things like [[ and ]] could reasonably occur in legitimate JavaScript code. Might be better to use something that never could.




回答2:


Forget regex and preprocessing. You should break up the template so that the variable parts aren't in the same string as the <script> parts.

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


template = """
    {head}

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

Finally, I want to avoid errors that .format(...) would produce when the template contains placeholders, such as {{dont_want_this_substituted}}, for which the passed dictionary doesn't contain a value. That is, I want to only substitute only certain placeholders, not all that appear in the template.

It might be hacky, but you can use collections.defaultdict, as shown in this answer. Code sample from that answer (modified).

from collections import defaultdict

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


来源:https://stackoverflow.com/questions/34214945/advanced-python-string-formatting-with-custom-placeholders

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!