为什么我可以将正常的callables和方法添加到集合中,但不能<some list>.append
(例如)?
例如:
>>> l = []
>>> s = set()
>>> s.add(l.append)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> type(l.append)
<type 'builtin_function_or_method'>
>>> type(map)
<type 'builtin_function_or_method'>
>>> s.add(map)
>>> def func(): print 'func'
...
>>> s.add(func)
>>> print s
set([<built-in function map>, <function func at 0x10a659758>])
编辑:我注意到l.append.__hash__()
也会出现此错误
答案 0 :(得分:7)
您无法将list
添加到集合中,因为列表是可变的。只能将不可变对象添加到集合中。
l.append
是一种实例方法。您可以将其视为元组(l, list.append)
- 也就是说,它是与特定列表l
相关联的list.append()方法。 list.append()方法是不可变的,但l
不是。因此,虽然您可以向该集添加list.append
,但无法添加l.append
。
这有效:
>>> s.add(list.append)
这不起作用:
>>> s.add((l, list.append))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
答案 1 :(得分:3)
您不是要添加list.append
。您正在尝试添加l.append
这是一个实例方法,而不是类方法。 list
个实例不可清除,显然它们的方法也不可清除。
这样想。你有2个清单:
lfoo = []
lbar = []
现在您要将各自的附加内容添加到您的设置中:
s = set()
s.add(lfoo.append)
s.add(lbar.append)
现在,当您对集合执行哈希查找时,您不能仅依赖实例方法的函数部分。实际上,lfoo
和lbar
最终使用相同的函数(list.append
)。所以这不是一个独特的哈希。使其独特的方式是将其附加到实例。但是,该实例不支持散列,因此该集合无法区分lfoo.append
和lbar.append
之间的区别。
答案 2 :(得分:2)
在Python中,list
个对象不可清除。我怀疑当你对一个实例方法进行哈希时,它会包含它所绑定的实例的哈希值。因此,您获得了TypeError
。