【问题标题】:Ignore str.format(**foo) if key doesn't exist in foo如果 foo 中不存在键,则忽略 str.format(**foo)
【发布时间】:2015-03-21 14:06:57
【问题描述】:

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

目前这很好,因为所有值都在字典中('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 变量中,我正在尝试创建我的“模板”。这意味着我需要拥有字典中所有可能的项目。

例如,下一段将失败,因为它正在查找此字典中不存在的 '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)

如果查找字典中不存在作为键的字符串替换,有没有办法让它忽略它?

【问题讨论】:

标签: python string python-3.x escaping string-interpolation


【解决方案1】:

您可以为此使用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>

【讨论】:

  • 这很好,我不知道Template/safe_substitute
  • 这很棒。谢谢你。我实际上使用了这些解决方案的组合。我正在使用默认字典和 safe_substitute 的这个想法。谢谢你们。
  • envsubst(1) 的绝佳替代品。非常感谢。
【解决方案2】:

我认为没有办法告诉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)

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

【讨论】:

    【解决方案3】:

    如果您还不知道密钥:

    你可以只写一个 dict 子类,如果它在字典中没有找到,它将返回键:

    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))
    

    【讨论】:

      猜你喜欢
      • 2019-12-13
      • 2016-04-03
      • 1970-01-01
      • 2022-11-04
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-29
      相关资源
      最近更新 更多