不可散列对象被散列¶
ID: py/hash-unhashable-value
Kind: problem
Security severity:
Severity: error
Precision: very-high
Tags:
- reliability
- correctness
Query suites:
- python-security-and-quality.qls
如果一个对象被用作字典中的键或集合的成员,那么它必须是可散列的,也就是说它必须定义一个 __hash__
方法。所有内置的不可变类型都是可散列的,但可变类型不是。常见的可散列类型包括所有数字、字符串(unicode
和 bytes
)以及 tuple
。常见的不可散列类型包括 list
、dict
和 set
。
为了将键存储在 dict
或 set
中,需要散列值。为了确定该值,会调用内置函数 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]
参考¶
Python 标准库:hash.
Python 语言参考:object.hash.
Python 标准库:映射类型 - dict.
Python 标准库:集合类型 - set, frozenset.