如果未在str.format中传递,则将值保留为空

mar*_*991 20 python string-formatting missing-data

我遇到了一个相当简单的问题,我无法想出一个优雅的解决方案.

我正在str.format一个函数中创建一个字符串,该函数在一个dict替换中传递以用于格式.我想创建字符串并使用值格式化它们,如果它们被传递,否则将它们留空.

防爆

kwargs = {"name": "mark"}
"My name is {name} and I'm really {adjective}.".format(**kwargs)
Run Code Online (Sandbox Code Playgroud)

应该回来

"My name is mark and I'm really ."
Run Code Online (Sandbox Code Playgroud)

而不是抛出KeyError(如果我们不做任何事情会发生什么).

令人尴尬的是,我甚至无法为这个问题提出一个不优雅的解决方案.我想我可以通过不使用来解决这个问题str.format,但如果可能的话,我宁愿使用内置(主要是我想要的).

注意:我事先并不知道将使用哪些密钥.如果有人包含一把钥匙但是没有把它放在kwargs dict中,我试图优雅地失败.如果我100%准确地知道将要查找哪些键,我只需填充所有键并完成它.

daw*_*awg 21

您可以按照PEP 3101中的建议操作并使用子类Formatter:

import string

class BlankFormatter(string.Formatter):
    def __init__(self, default=''):
        self.default=default

    def get_value(self, key, args, kwds):
        if isinstance(key, str):
            return kwds.get(key, self.default)
        else:
            return string.Formatter.get_value(key, args, kwds)

kwargs = {"name": "mark", "adj": "mad"}     
fmt=BlankFormatter()
print fmt.format("My name is {name} and I'm really {adj}.", **kwargs)
# My name is mark and I'm really mad.
print fmt.format("My name is {name} and I'm really {adjective}.", **kwargs)
# My name is mark and I'm really .  
Run Code Online (Sandbox Code Playgroud)

从Python 3.2开始,您可以使用.format_map作为替代方案:

class Default(dict):
    def __missing__(self, key):
        return '{'+key+'}'

kwargs = {"name": "mark"}

print("My name is {name} and I'm really {adjective}.".format_map(Default(kwargs)))
Run Code Online (Sandbox Code Playgroud)

打印:

My name is mark and I'm really {adjective}.
Run Code Online (Sandbox Code Playgroud)

  • 我还要添加`或isinstance(key,unicode)` (4认同)

And*_*ark 12

这是一个使用的选项collections.defaultdict:

>>> from collections import defaultdict
>>> kwargs = {"name": "mark"}
>>> template = "My name is {0[name]} and I'm really {0[adjective]}."
>>> template.format(defaultdict(str, kwargs))
"My name is mark and I'm really ."
Run Code Online (Sandbox Code Playgroud)

请注意,我们不再使用**将字典解压缩为关键字参数,并且格式说明符使用{0[name]}{0[adjective]},这表示我们应该对第一个参数执行键查找以分别format()使用"name""adjective".通过使用defaultdict缺少的键将导致空字符串而不是引发KeyError.