Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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
我可以使用对象(类的实例)作为Python中的字典键吗?_Python_List_Dictionary_Tuples - Fatal编程技术网

我可以使用对象(类的实例)作为Python中的字典键吗?

我可以使用对象(类的实例)作为Python中的字典键吗?,python,list,dictionary,tuples,Python,List,Dictionary,Tuples,我想使用类实例作为字典键,如: classinstance = class() dictionary[classinstance] = 'hello world' Python似乎无法将类作为字典键处理,还是我错了? 此外,我可以使用元组列表,比如[(classinstance,helloworld),…],而不是字典,但这看起来非常不专业。 您有解决该问题的线索吗?以下代码运行良好,因为默认情况下,您的类对象是可哈希的: Class Foo(object): def __init__

我想使用类实例作为字典键,如:

classinstance = class()
dictionary[classinstance] = 'hello world'
Python似乎无法将类作为字典键处理,还是我错了? 此外,我可以使用元组列表,比如[(classinstance,helloworld),…],而不是字典,但这看起来非常不专业。
您有解决该问题的线索吗?

以下代码运行良好,因为默认情况下,您的类对象是可哈希的:

Class Foo(object):
    def __init__(self):
        pass

myinstance = Foo()
mydict = {myinstance : 'Hello world'}

print mydict[myinstance]
输出: 你好,世界

此外,为了获得更高级的使用,您应该阅读以下文章:


您的实例需要是可散列的。报告告诉我们:

如果一个对象的哈希值在其生存期内从不改变(它需要一个
\uuuuu hash\uuuu()
方法),并且可以与其他对象进行比较(它需要一个
\uuuu eq\uuuu()
\uu cmp\uuuuu()
方法),则该对象是可哈希的。比较相等的可散列对象必须具有相同的散列值

哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值

Python的所有不可变内置对象都是可散列的,而没有可变容器(如列表或字典)是可散列的。默认情况下,作为用户定义类实例的对象是可散列的;它们都比较不相等,它们的哈希值是它们的id()


将实例用作字典键没有什么错,只要它符合以下条件:字典键必须是不可变的

尝试在类中实现哈希eq方法

例如,我制作了一个简单的哈希字典类:

class hashable_dict:
    def __init__(self, d):
        self.my_dict = d
        self.my_frozenset = frozenset(d.items())
    def __getitem__(self, item):
        return self.my_dict[item]
    def __hash__(self):
        return hash(self.my_frozenset)
    def __eq__(self, rhs):
        return isinstance(rhs, hashable_dict) and self.my_frozenset == rhs.my_frozenset
    def __ne__(self, rhs):
       return not self == rhs
    def __str__(self):
        return 'hashable_dict(' + str(self.my_dict) + ')'
    def __repr__(self):
        return self.__str__()

没问题-对我来说很好用。为什么你认为它不起作用-你有例外吗?你们有什么python版本?我使用Python2.7+TwistedFramework。这条消息向我显示:exceptions.KeyError:So-我确信(或者只是这么认为)此异常不是在您将元素添加到dict(如您的示例中)时引发的,而是在您尝试获取它时引发的-检查您之前在其中输入的内容-您用作键的实例可能已更改。是的,它似乎发生了,wenn我想删除它。检查一些细节…当我试图得到它时,它也会发生。这是正确的,但会产生误导。默认情况下,所有对象实例都是可散列的。散列代码将是对象实例的唯一标识符。“它们的散列值是它们的id()。”这在python3.x之后发生了变化,请参见KISS:保持简单S*:-)我认为ltsstar不需要这个复杂的代码。我不同意。我认为一个写在字典里的类的例子是非常有用的。对于初学者来说,字典似乎很神奇,理解为什么对象会以相同/不同的方式对对象进行散列,以确保代码按预期工作,这一点非常重要。你和我可能只是个人品味不同,但我总是喜欢例子,尤其是在15行左右的时候同样的问题,使用元组还是更好?很难说元组更好。元组更简单。但是,如果您需要将实例存储为字典键,这可能会更好,但也更复杂。:)