Python ** kwargs中的KeyError

时间:2018-11-03 03:12:30

标签: python python-3.x

仅第一个打印命令有效。我不知道为什么。我想根据传入的内容显示不同的前缀和后缀。

# We are going to have a word and a prefix or a suffix before or after
# that word

def joinWords(string, **sFox):
    if sFox['prefix']: 
        return sFox['prefix'] + string
    elif sFox['suffix']: 
        return string + sFox['suffix']
    return string




#Why does this work?
#print(joinWords("Cookie", prefix="sugar"))

#And this does not?
#print(joinWords("Cookie", suffix="monster"))

4 个答案:

答案 0 :(得分:1)

引用sFox没有的密钥会引发错误。

此外,即使提供了后缀和前缀,当前代码似乎也只能选择前缀。

遍历(key, value)中的一对sFox,您可能想要按以下方式更改代码。

def joinWords(string, **sFox):
    for key, value in sFox.items():
        if key == 'prefix':
            string = value + string
        elif key == 'suffix':
            string = string + value
    return string

答案 1 :(得分:1)

您遇到的问题是kwargs将不包含未指定的键。当您尝试索引字典中不存在的键时,它将引发一个KeyError

最直接的解决方案是在尝试访问密钥之前检查密钥是否存在:

    if 'prefix' in sFox and sFox['prefix']:

还有更好的Python方式可以做到这一点。如前所述,dict.get()是默认值的一个不错的选择:

    if sFox.get('prefix'):

这样,如果prefix'不在字典中,则值将为None,它的计算结果为布尔值false,可以完美地完成技巧。

当然,如果您真的不需要随机的关键字参数,请尝试使用默认参数:

def joinWords(string, prefix=None, suffix=None):
    if prefix:
        return prefix + string
    elif suffix: 
        return string + suffix
    return string

IMO,除非您尝试了解关键字参数包,否则这可能是一个更好的解决方案。

答案 2 :(得分:1)

问题是您使用sFox['prefix'],如果在调用print(joinWords("Tits", suffix="monster"))时未传递密钥参数前缀,则会引发密钥错误。

要解决此问题,您可以使用sFox.get('prefix'),当您不传递前缀关键字参数时,它将返回默认值None。

答案 3 :(得分:1)

sFox['prefix']将在sFox中返回键为prefix的项目(如果存在),否则引发KeyError

更糟糕的是,即使{{1}中存在if sFox['prefix']: prefix仍可能不执行代码,因为sFox可能会存储值sFox['prefix']

我认为您实际上要使用此行来测试False 是否包含密钥为sFox的项目。在Python中,使用语法prefix

您在其中重写的程序如下所示:

[key] in [dict]

现在要回答另一个问题:自从您def joinWords(string, **sFox): if `prefix` in sFox: return sFox['prefix'] + string elif `suffix` in sFox: return string + sFox['suffix'] return string 在该部分以来,只有第一部分被执行,即离开该函数。如果要两个部分都执行,则必须在添加后缀和前缀后才返回。这是一个示例:

return

最后,向组合中添加一些语法糖-看一下python default parameter values。通过这些,您可以像这样定义函数:

def joinWords(string, **sFox):
    if `prefix` in sFox:
        string = sFox['prefix'] + string
    if `suffix` in sFox: # Notice only "if" not "elif"
        string =  string + sFox['suffix']
    return string