Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python3中是否可以使用类作为字典键?_Python_Hash_Dictionary_Python 3.x - Fatal编程技术网

在Python3中是否可以使用类作为字典键?

在Python3中是否可以使用类作为字典键?,python,hash,dictionary,python-3.x,Python,Hash,Dictionary,Python 3.x,我试图减少代码中的复制/粘贴,但却偶然发现了这个问题。我搜索了答案,但所有答案都使用类的实例作为键,我找不到任何关于使用类定义本身作为键的内容(我不知道是否可能) 我的代码是: # All chunkFuncs keys are class definitions, all values are functions chunkFuncs = {Math_EXP : Math_EXPChunk, Assignment : AssignmentChunk, Function : FunctionCh

我试图减少代码中的复制/粘贴,但却偶然发现了这个问题。我搜索了答案,但所有答案都使用类的实例作为键,我找不到任何关于使用类定义本身作为键的内容(我不知道是否可能)

我的代码是:

# 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
错误是这样的

TypeError: unhashable type: 'Assignment'
以下是类定义:

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])),')'
有没有其他方法可以达到同样的效果


谢谢。

您应该能够,是的,但是您可能需要额外的
类型
呼叫:

>>> class X:
...     pass
...
>>> class_map = {X: 5}
>>> my_x = X()
>>> class_map[type(my_x)]
5

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

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

chunkFuncs = {Math_EXP : Math_EXPChunk, Assignment : AssignmentChunk, Function : FunctionChunk}
如果尝试使用不可损坏的键构造dict,dict创建将立即失败:

>>> {[]: 3}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
最好的猜测是它是一个不可损坏的
赋值的实例:

>>> 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) 2582159 >>>散列(mylist()) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:不可损坏的类型:“mylist”
看到了吗
mylist
是可散列的,但实例
mylist()
不是


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

只要类是可哈希的,它就可以工作。你试过了吗?发生了什么事?@SethMMorton我更新了问题以显示错误和我正在使用的代码,很抱歉过早发布。您应该查看此帖子:。检查第二个答案的后半部分。如果类不可散列,则不能将其用作字典键。
pyPeg.List
从何而来?发生了一些奇怪的事情。也许
pyPeg
过于花哨;-)框架与元类玩游戏-你必须努力使类对象不易损坏。顺便说一句,你没有显示回溯:哪一行触发了
TypeError
?是的,您可以使用
id(some_class_object)
作为dict键。您是正确的,我在阅读您的回复后发现的解决方案是使用在前面的isinstance()调用中找到的类型作为dict键,而不是类型本身的实例。简单的错误,但所有其他的复杂性使它溜走了。谢谢
>>> class mylist(list):
...   pass
...
>>> hash(mylist)
2582159
>>> hash(mylist())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'mylist'