python - 字符串模板 - 同一键的不同值
我有一个 SQL 模板,需要在其中替换随机 UUID。
from string import Template
import uuid
def gen_uuid():
return str(uuid.uuid4())
s = """
insert ... values('foo', ${uuid});
insert ... values('bar', ${uuid});
insert ... values('baz', ${uuid});
"""
mappings = {
"uuid": gen_uuid # how??
}
template = Template(s)
print template.safe_substitute(mappings)
如何将不同的 UUID 值绑定到同一个模板键?
更新
好吧..我最终覆盖了getitem
。不理想但有效..
class UUIDDict(dict):
def __init__(self, *args, **kwargs):
self.update(*args, **kwargs)
def __getitem__(self, key):
if key == 'uuid':
return str(uuid.uuid4())
return super(UUIDDict, self).__getitem__(key)
I have an SQL template where I need to substitute random UUIDs.
from string import Template
import uuid
def gen_uuid():
return str(uuid.uuid4())
s = """
insert ... values('foo', ${uuid});
insert ... values('bar', ${uuid});
insert ... values('baz', ${uuid});
"""
mappings = {
"uuid": gen_uuid # how??
}
template = Template(s)
print template.safe_substitute(mappings)
How can I bind different UUIDs values to the same template key?
Update
Ok.. I ended up overriding getitem
. Not ideal but works..
class UUIDDict(dict):
def __init__(self, *args, **kwargs):
self.update(*args, **kwargs)
def __getitem__(self, key):
if key == 'uuid':
return str(uuid.uuid4())
return super(UUIDDict, self).__getitem__(key)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
string.Template() 并非旨在用多个值替换单键。其他模板系统可能支持这一点,但 string.Template 本来就很简单。
话虽这么说,在循环中执行您想要的操作,然后使用 str.join 组合结果并不难:
根据 OP 的建议,可以创建一个自定义字典来构建一个每次查找时使用 new uuid() :
string.Template() isn't designed to substitute multiple values for a single key. Other templating systems may support this, but string.Template is meant to be dirt simple.
That being said, it isn't hard to do what you want in a loop and then combine the results using str.join:
As suggested by the OP, a custom dictionary can be created that will build a new uuid() on each lookup:
第一个问题是您没有将 gen_uuid 的结果传递给模板,而是引用函数对象本身。它应该是:
使用您当前的方法, gen_uuid 函数将仅计算一次,因此每个语句将使用相同的值。
为什么不做这样的事情呢?:
The first problem is you're not passing the result of gen_uuid to the template, you're referencing the function object itself. It should be:
With your current approach the gen_uuid function will only be evaluated once, so the same value will be used for each statement.
Why not do something like this instead?:
这是使用“默认字典”(
defaultdict
) 的解决方案:结果将类似于以下内容:
使用单个参数(即工厂函数)创建
defaultdict
。每次在默认字典中查找未知键时,它都会调用该函数,将该值绑定到该键,然后返回该键。因此它会为每个变量分配一个新的 UUID。主要缺点是不能使用单个变量
${uuid}
;您必须为每个 uuid 定义一个新变量。话又说回来,从长远来看,这可能是更好的做法:这样,您可以在再次需要时访问模板中每个值的特定 UUID。在进行模板替换后,您甚至可以直接从 Python 代码访问 UUID:Here is a solution that uses a "default dictionary" (
defaultdict
):The result will be something like the following:
A
defaultdict
is created with a single argument, a factory function. Every time an unknown key is looked up in a default dictionary, it calls that function, binds that value to the key, and then returns the key. Thus it will assign a new UUID to each variable.The main disadvantage is that you can't use the single variable
${uuid}
; You will have to define a new variable for each uuid. Then again, this may be better practice in the long run: that way, you can access the particular UUID for each value in the template should you need it again. You could even access the UUIDs direct from the Python code, after you do the template substitution: