CodeQL 文档

不可散列对象被散列

ID: py/hash-unhashable-value
Kind: problem
Security severity: 
Severity: error
Precision: very-high
Tags:
   - reliability
   - correctness
Query suites:
   - python-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

如果一个对象被用作字典中的键或集合的成员,那么它必须是可散列的,也就是说它必须定义一个 __hash__ 方法。所有内置的不可变类型都是可散列的,但可变类型不是。常见的可散列类型包括所有数字、字符串(unicodebytes)以及 tuple。常见的不可散列类型包括 listdictset

为了将键存储在 dictset 中,需要散列值。为了确定该值,会调用内置函数 hash(),该函数反过来会调用对象上的 __hash__ 方法。如果对象的类没有 __hash__ 方法,那么会引发 TypeError

建议

由于这个问题通常表示逻辑错误,因此无法给出解决问题的通用方法。可以将可变集合转换为等效的不可变集合,如果适用。例如,可以通过将所有 set 实例转换为 frozenset 实例来散列集合。

示例

list 不是可散列的。在这个示例中,尝试将 list 用作映射中的键,这会导致 TypeError 失败。


def lookup_with_default_key(mapping, key=None):
    if key is None:
        key = [] # Should be key = ()
    return mapping[key]

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私