关于hash:是否可以在Python 3中将类用作字典键?

Is it possible to use a class as a dictionary key in Python 3?

我正在尝试减少代码中的复制/粘贴,但遇到了这个问题。我已经搜索了答案,但是所有的答案都使用一个类的实例作为键,我在使用类定义本身作为键时找不到任何内容(我不知道是否可能)。

我的代码是:

1
2
3
4
5
6
7
8
9
# All chunkFuncs keys are class definitions, all values are functions
chunkFuncs = {Math_EXP : Math_EXPChunk, Assignment : AssignmentChunk, Function : FunctionChunk}

def Chunker(chunk, localScope):
    for chunkType in chunkFuncs:
        if isinstance(chunk,chunkType):
            # The next line is where the error is raised
            localScope = chunkFuncs[chunk](chunk,localScope)
            return localScope

错误是这样的

1
TypeError: unhashable type: 'Assignment'

以下是类定义:

1
2
3
4
5
6
7
8
class Math_EXP(pyPeg.List):
    grammar = [Number,Symbol],pyPeg.maybe_some(Math_OP,[Number,Symbol])

class Assignment(pyPeg.List):
    grammar = Symbol,'=',[Math_EXP,Number]

class Function(pyPeg.List):
    grammar = Symbol,'(',pyPeg.optional(pyPeg.csl([Symbol,Number])),')'

有没有其他方法可以达到同样的效果?

谢谢。


好吧,评论已经失控了;-)

现在似乎可以确定类对象不是问题所在。如果是的话,在第一次构造dict时,错误会在第一行触发:

1
chunkFuncs = {Math_EXP : Math_EXPChunk, Assignment : AssignmentChunk, Function : FunctionChunk}

如果试图用不可显示的键构造dict,则dict创建会立即失败:

1
2
3
4
>>> {[]: 3}
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

但你已经超越了这一界限,而Assignment是你所构建的口述的关键。所以错误在这一行:

1
        localScope = chunkFuncs[chunk](chunk,localScope)

最好的猜测是,这是Assignment的一个例子,它是不可改变的:

1
2
3
4
5
6
7
8
9
>>> class mylist(list):
...   pass
...
>>> hash(mylist)
2582159
>>> hash(mylist())
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
TypeError: unhashable type: 'mylist'

看到了吗?mylist是可散列的,但实例mylist()不是。

稍后:最好的猜测是,你将无法绕过这个。为什么?由于基类的名称,pyPeg.List。如果它像python列表一样是可变的,那么实例将不可散列——也不应该是(可变对象总是像dict键那样危险的)。您仍然可以索引id(the_instance)的一个dict,但是如果不了解更多关于您的代码,这在语义上是否正确是我无法猜测的。


您应该能够,是的,但是您可能需要一个额外的type电话:

1
2
3
4
5
6
7
>>> class X:
...     pass
...
>>> class_map = {X: 5}
>>> my_x = X()
>>> class_map[type(my_x)]
5