3

我有一堂课Commit

class Commit:
    def __init__(self, uid, message):
        self.uid = uid
        self.message = message

    def __str__(self):
        print(self.__dict__)
        return textwrap.dedent('''\
        Commit: {uid}

        {message}
        ''').format(self.__dict__)

这对我来说似乎是正确的;从调用None的输出中可以看出,两个键都存在且非:print

{'message': 'Hello, world!', 'uid': 1}

但是,str.format()对列表行的调用会引发KeyError.

回溯(最近一次通话最后):
  文件“../Pynewood/pnw”,第 7 行,在
    cli(sys.argv)
  文件“/Users/daknok/Desktop/Pynewood/pynewood/cli.py”,第 11 行,在 cli
    打印(提交)
  文件“/Users/daknok/Desktop/Pynewood/pynewood/commit.py”,第 14 行,在 __str__
    ''').format(self.__dict__)
键错误:'uid'

为什么我会收到此错误,而字典中显然存在键?

4

2 回答 2

5

str.format()需要 kwargs,因此您需要使用**.

def __str__(self):
    return textwrap.dedent('''\
    Commit: {uid}

    {message}
    ''').format(**self.__dict__)
于 2012-07-21T10:25:29.573 回答
3

Radek Slupik是对的,它str.format需要单独的关键字参数,并且在问题的代码中,dict它只是作为第一个位置参数传递format,它将{0}在格式字符串中扩展。所以应该使用。str.format(**mapping)

但是从 Python 3.2 开始,您可以改用它。它的工作原理类似于,但它不会将映射转换为. 这允许我们为 提供自定义映射类,就像文档中的示例一样:str.format_map(mapping)str.format(**mapping)dictformat

>>> class Default(dict):
...     def __missing__(self, key):
...         return key
...
>>> '{name} was born in {country}'.format_map(Default(name='Guido'))
'Guido was born in country'

它看起来也更好,并且可能会带来微小的性能提升。

于 2012-07-21T15:37:09.157 回答