шаблон питона со значением по умолчанию - PullRequest
0 голосов
/ 03 июля 2018

В питоне я могу использовать шаблон с

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

как я могу определить значение по умолчанию в шаблоне? И вызвать шаблон без какого-либо значения.

print templ.substitute()
редактировать

И когда я звоню без параметров, получаю значение по умолчанию, например

 print templ.substitute()
 >> hello name

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Если значением по умолчанию является имя переменной (как в вопросе), недостающие данные могут быть добавлены автоматически:

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)
0 голосов
/ 04 июля 2018

Метод Template.substitute принимает аргумент mapping в дополнение к аргументам ключевого слова . Ключевое слово 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 со значениями по умолчанию substitute.

0 голосов
/ 03 июля 2018

Вы можете создать свой прокси для класса 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...