当密钥明确存在时,为什么会出现KeyError?

时间:2012-07-21 10:21:46

标签: python dictionary python-3.x

我有一个班级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

Traceback (most recent call last):
  File "../Pynewood/pnw", line 7, in 
    cli(sys.argv)
  File "/Users/daknok/Desktop/Pynewood/pynewood/cli.py", line 11, in cli
    print(commit)
  File "/Users/daknok/Desktop/Pynewood/pynewood/commit.py", line 14, in __str__
    ''').format(self.__dict__)
KeyError: 'uid'

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

2 个答案:

答案 0 :(得分:5)

str.format()期待kwargs,因此您需要使用**扩展字典。

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

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

答案 1 :(得分:3)

Radek Slupik 是对的,str.format需要单独的关键字参数,而在问题的代码中,dict只是作为第一个位置参数传递给{{1这将在格式字符串中的format上进行扩展。所以应该使用{0}

但是从Python 3.2开始,您可以使用str.format(**mapping)代替。它与str.format_map(mapping)的工作方式类似,但它不会将映射转换为str.format(**mapping)。这允许我们将自定义映射类提供给dict,如文档中的示例所示:

format

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