我对为Python字符串模板设置自定义分隔符感到困惑。我看到一个教程视频说要使用自定义子类。所以我做了,它有效:
from string import Template
class MyTemplate(Template):
delimiter = '#'
d = {'key':'value'}
t = MyTemplate('key is #key')
print(t.substitute(d))
#prints "key is value" as expected
所以我在想,如果我要做的就是在模板上更改一个类变量,那么不应该做以下工作吗?
from string import Template
Template.delimiter = '#'
d = {'key':'value'}
t = Template('key is #key')
print(t.substitute(d))
#prints "key is #key", but why?
我想也许我不得不出于某种原因创建一个子类。所以我想我会编写一个子类,但我会允许设置分隔符:
from string import Template
class MyTemplate(Template):
@classmethod
def setDelim(cls, delim):
cls.delimiter = delim
MyTemplate.setDelim('#')
d = {'key':'value'}
t = MyTemplate('key is #key')
print(t.substitute(d))
#prints "key is #key", because it is still looking for '$' as delimiter
我在Python2和Python3中都证实了这种行为。在所有三个示例中,类变量定界符已正确设置,但仅在第一个示例中它确实有效。有人可以解释一下吗?
答案 0 :(得分:2)
这是如何在标准python库中定义Template
类的实现细节。具体来说,如果您查看string.py source,Template
是使用metaclass实现的,该{{3}}会根据<{1}}属性的值在类中添加额外的模式属性。 em>类初始化时间。
初始化类后,替换模式被冻结,因此您必须使用推荐的子类方法在类定义时覆盖delimiter
或执行更高级的操作来覆盖元类行为。
E.g。
delimiter
答案 1 :(得分:1)
Template
继承自metaclass。元类的__init__
方法使用Template
的分隔符执行一些设置。 (具体来说,它创建用于匹配分隔文本的正则表达式。)
在此设置发生后更改delimiter
不会重新初始化设置,因此您需要使用子类,以便使用所需的分隔符值。