具有默认值的python模板

时间:2018-07-03 18:19:07

标签: python python-2.7

在python中,我可以将模板与

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

如何在模板中定义默认值? 并调用没有任何值的模板。

print templ.substitute()
编辑

当我不带参数的电话获取默认值时,示例

 print templ.substitute()
 >> hello name

3 个答案:

答案 0 :(得分:3)

Template.substitute方法使用mapping 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

print templ.safe_substitute()                       # prints hello ${name}
print templ.safe_substitute(defaults)               # prints hello default
print templ.safe_substitute(defaults, name="world") # prints hello world

如果您绝对坚持不向substitute传递任何参数,则可以继承Template:

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的{​​{1}}相比,其明确性和可读性较低。

答案 1 :(得分:0)

您可以创建Template类的代理,并在其中存储替代项。

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兼容性。

答案 2 :(得分:0)

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

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)