如果 foo 中不存在密钥,则忽略 str.format(**foo)

Ignore str.format(**foo) if key doesn't exist in foo

我正在尝试整理电子邮件模板。消息内容将取决于字典中的值。但是,字典可能不会每次都包含所有键。

这目前没问题,因为所有值都在字典中('Title''Surname''Additional Details'):

practise_dict = {"Additional Details":"blah blah blah blah", "Title": "Mr", "Surname": "Smith", "URL": "/test/tester"}

msg = """From: John Smith <no-reply@somethingsomething.co.uk>
To: {Title} {Surname} <blah@blahblah.co.uk>
MIME-Version: 1.0
Content-type: text/html
Subject: New Website Enquiry
This is an e-mail message to be sent in HTML format
{Additional Details}
<b>This is HTML message.</b>
<h1>This is headline.</h1>
`""".format(**practise_dict)

print(msg)

msg 变量中,我正在尝试创建我的 'template'。这意味着我需要拥有所有可能出现在字典中的项目。

例如,下一段将失败,因为它正在寻找此字典中不存在的 'Date'

practise_dict = {"Additional Details":"blah blah blah blah", "Title": "Mr", "Surname": "Smith", "URL": "/test/tester"}

msg = """From: John Smith <no-reply@somethingsomething.co.uk>
To: {Title} {Surname} <blah@blahblah.co.uk>
MIME-Version: 1.0
Content-type: text/html
Subject: New Website Enquiry
This is an e-mail message to be sent in HTML format
{Additional Details}
{Date}
<b>This is HTML message.</b>
<h1>This is headline.</h1>
`""".format(**practise_dict)

print(msg)

如果查找字典中不存在作为键的字符串替换,是否可以要求它忽略该字符串替换?

我认为没有办法告诉 format 某些替换是可选的。但是,这里有两个解决方法。

如果只缺少一个字段,请尝试以下操作:

msg = """...""".format(Date=practise_dict.pop("Date", ""), # handle optional field
                       **practise_dict) # pass the rest as before

但是,请注意,这会修改 practise_dict,如果有多个值需要处理,将会很尴尬。

如果可能缺少多个字段,或者您不想修改字典,则可能更可取:

defaults = {"Date": "", "Additional Details": ""} # define optional fields
defaults.update(practise_dict) # override user data where available
msg = """...""".format(**defaults)

对于您没有明确提供替代方案的键,这两种方法仍然会失败,这允许您将某些字段设为必填。

您可以使用 Templatesafe_substitute

from string import Template

practise_dict = {"Additional_Details":"blah blah blah blah", "Title": "Mr", "Surname": "Smith", "URL": "/test/tester"}

msg = """From: John Smith <no-reply@somethingsomething.co.uk>
To: $Title $Surname <blah@blahblah.co.uk>
MIME-Version: 1.0
Content-type: text/html
Subject: New Website Enquiry
This is an e-mail message to be sent in HTML format
$Additional_Details
$Date
<b>This is HTML message.</b>
<h1>This is headline.</h1>
`"""

s = Template(msg).safe_substitute(**practise_dict)
print(s)

输出

From: John Smith <no-reply@somethingsomething.co.uk>
To: Mr Smith <blah@blahblah.co.uk>
MIME-Version: 1.0
Content-type: text/html
Subject: New Website Enquiry
This is an e-mail message to be sent in HTML format
blah blah blah blah
$Date
<b>This is HTML message.</b>
<h1>This is headline.</h1>

如果您还不知道密钥:

你可以只写一个 dict 子类,如果在字典中找不到它,它将 return 键:

class FailsafeDict(dict):
    def __getitem__(self, item):
        try:
            return super().__getitem__(item)
        except KeyError:
            return "{" + str(item) + "}"
        # end try
    # end def
# end class

这通过覆盖处理 dict[item] 调用的 __getitem__(item) 函数来实现。

你可以这样使用它:

f = FailsafeDict({"yo": "lo", "foo": "bar"})
text = "{yo}! {lol}! {foo}!".format(**f)
print(text)  

打印 lo! {lol}! bar!.

你的情况是

msg = """...""".format(**FailsafeDict(practise_dict))