子类化模板以提供默认参数
Subclassing Template to provide default arguments
我正在从 string
继承 Template
以赋予它一些额外的默认功能。这个想法是它的查找超出传递的字典首先扩展到 locals()
,然后扩展到 globals()
,最后扩展到默认值(例如,扩展到 '-'
)。所以这就是我写的:
class MyTemplate(Template):
def substitute_default(*args, **kws):
if not args:
raise TypeError("descriptor 'substitute' of 'Template' object needs an argument")
self, *args = args # allow the "self" keyword be passed
if len(args) > 1:
raise TypeError('Too many positional arguments')
if not args:
mapping = kws
elif kws:
mapping = ChainMap(kws, args[0])
else:
mapping = args[0]
def convert(mo):
named = mo.group('named') or mo.group('braced')
if named is not None:
val = mapping.get(named, locals().get(named, globals().get(named, '-')))
return '%s' % (val,)
if mo.group('escaped') is not None:
return self.delimiter
if mo.group('invalid') is not None:
self._invalid(mo)
raise ValueError('Unrecognized named group in pattern', self.pattern)
return self.pattern.sub(convert, self.template)
带有juice的那一行是这样的:
val = mapping.get(named, locals().get(named, globals().get(named, '-')))
我是这样测试的:
a = 'global_foo'
def f():
b = 'local_foo'
t = MyTemplate('''a=$a, b=$b, c=$c, d=$d''')
text = t.substitute_default({'c': 'foo', 'd': 'bar'})
print(text)
f() # -> a=global_foo, b=-, c=foo, d=bar
如您所见,globals()
查找有效,但 locals()
无效..
- 有人知道为什么会这样吗?
- 有更好的方法吗?
问题是 locals()
是您的 convert
函数的局部变量,而您希望它引用 f
局部变量。
您必须以某种方式传递 locals()
字典,无论是在构造函数中还是在其他地方,它才能工作。
我正在从 string
继承 Template
以赋予它一些额外的默认功能。这个想法是它的查找超出传递的字典首先扩展到 locals()
,然后扩展到 globals()
,最后扩展到默认值(例如,扩展到 '-'
)。所以这就是我写的:
class MyTemplate(Template):
def substitute_default(*args, **kws):
if not args:
raise TypeError("descriptor 'substitute' of 'Template' object needs an argument")
self, *args = args # allow the "self" keyword be passed
if len(args) > 1:
raise TypeError('Too many positional arguments')
if not args:
mapping = kws
elif kws:
mapping = ChainMap(kws, args[0])
else:
mapping = args[0]
def convert(mo):
named = mo.group('named') or mo.group('braced')
if named is not None:
val = mapping.get(named, locals().get(named, globals().get(named, '-')))
return '%s' % (val,)
if mo.group('escaped') is not None:
return self.delimiter
if mo.group('invalid') is not None:
self._invalid(mo)
raise ValueError('Unrecognized named group in pattern', self.pattern)
return self.pattern.sub(convert, self.template)
带有juice的那一行是这样的:
val = mapping.get(named, locals().get(named, globals().get(named, '-')))
我是这样测试的:
a = 'global_foo'
def f():
b = 'local_foo'
t = MyTemplate('''a=$a, b=$b, c=$c, d=$d''')
text = t.substitute_default({'c': 'foo', 'd': 'bar'})
print(text)
f() # -> a=global_foo, b=-, c=foo, d=bar
如您所见,globals()
查找有效,但 locals()
无效..
- 有人知道为什么会这样吗?
- 有更好的方法吗?
问题是 locals()
是您的 convert
函数的局部变量,而您希望它引用 f
局部变量。
您必须以某种方式传递 locals()
字典,无论是在构造函数中还是在其他地方,它才能工作。