【问题标题】:Why am I getting a KeyError when the key clearly exists?当密钥明显存在时,为什么我会收到 KeyError?
【发布时间】:2012-07-21 10:21:46
【问题描述】:

我有一堂课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__)

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

{'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'

为什么我得到这个错误,而字典中显然存在键?

【问题讨论】:

  • 您也可以使用vars(self)。我认为它看起来比self.__dict__

标签: python dictionary python-3.x


【解决方案1】:

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

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

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

【讨论】:

  • +1。显示的示例格式字符串 here
【解决方案2】:

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

但从 Python 3.2 开始,您可以改用 str.@987654321@(<em>mapping</em>)。它的工作方式与str.format(**<em>mapping</em>) 类似,但它不会将映射 转换为dict。这允许我们为format 提供自定义映射类,就像文档中的示例一样:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多