具有默认值的python模板

2024-05-15 17:52:47 发布

您现在位置:Python中文网/ 问答频道 /正文

在python中,我可以使用

from string import Template
templ = Template('hello ${name}')
print templ.substitute(name='world')

如何在模板中定义默认值? 调用模板而不带任何值。在

^{pr2}$ 编辑

当我不带参数调用时,会得到默认值,例如

 print templ.substitute()
 >> hello name

Tags: namefromimport模板编辑helloworld参数
3条回答

如果默认值是变量名(如问题中所示),则可以自动添加缺少的数据:

class MyTemplate(Template):
    def substitute(self, *args, **kwds):
        try:
            return super().substitute(*args, **kwds)
        except KeyError as err:
            key = str(err.args[0])
            kwds[key] = key 
            return self.substitute(*args, **kwds)

Template.substitute方法采用^{} argument in addition to keyword arguments。关键字参数重写mapping位置参数提供的参数,这使得mapping成为实现默认值的自然方法,而无需子类化:

from string import Template
defaults = { "name": "default" }
templ = Template('hello ${name}')
print templ.substitute(defaults)               # prints hello default
print templ.substitute(defaults, name="world") # prints hello world

这也适用于safe_substitute

^{pr2}$

如果您绝对坚持不向substitute传递参数,则可以将模板子类化:

class DefaultTemplate(Template):
    def __init__(self, template, default):
        self.default = default
        super(DefaultTemplate, self).__init__(template)

    def mapping(self, mapping):
        default_mapping = self.default.copy()
        default_mapping.update(mapping)
        return default_mapping

    def substitute(self, mapping=None, **kws):
        return super(DefaultTemplate, self).substitute(self.mapping(mapping or {}), **kws)

    def substitute(self, mapping=None, **kws):
        return super(DefaultTemplate, self).safe_substitute(self.mapping(mapping or {}), **kws)

然后像这样使用它:

DefaultTemplate({ "name": "default" }).substitute()

尽管我发现这比仅仅传递一个mapping并默认为substitute更不明确,可读性也更差。在

您可以创建模板类的代理并在那里存储替代项。在

from string import Template
from copy import copy


class TemplateWithDefaults(Template):

    def __init__(self, template, **defaults):
        self.defaults = defaults or {}
        super(TemplateWithDefaults, self).__init__(template)

    def build_mapping(self, *args, **kwargs):
        mapping = copy(self.defaults)
        if len(args) == 1:
            mapping.update(args[0])
        mapping.update(kwargs)
        return mapping

    def substitute(*args, **kwargs):
        self, args = args[0], args[1:]
        mapping = self.build_mapping(*args, **kwargs)
        return super(TemplateWithDefaults, self).substitute(mapping, **kwargs)

    def safe_substitute(*args, **kwargs):
        self, args = args[0], args[1:]
        mapping = self.build_mapping(*args, **kwargs)
        return super(TemplateWithDefaults, self).safe_substitute(mapping, **kwargs)

template = TemplateWithDefaults("$wow", wow=1)

print template.substitute() # outputs 1
print template.substitute(wow=2) # outputs 2
print template.substitute({"wow": 2}) # outputs 2
print template.substitute() # outputs 1 (means no side effects)

UPD:编辑代码来处理dict作为第一个参数。原始api兼容性。在

相关问题 更多 >