On Thu, Aug 06, 2020 at 12:17:17PM +0800, ZHAOWANCHENG wrote: > the doc of dictionary said "if a tuple contains any mutable object either > directly or indirectly, it cannot be used as a key." > i think a instance of user-defined class is mutable, but i found it can be > placed into a tuple that as a key of a dict: > >>> class mycls(object): > ... a = 1 > ... > >>> me = mycls() > >>> me.a = 2 # mutable? > >>> {(1, me): 'mycls'} > {(1, <__main__.mycls object at 0x0000022824DAD668>): 'mycls'} > >>> > > > So are instances of user-defined classes mutable or immutable?
A more specific description of objects that can be keys in a dictionary can be found on the documentation: https://docs.python.org/3/library/stdtypes.html#mapping-types-dict To be a key in a dictionary, an object must be *hashable*. The spec for hashable objects is also in the documentation: https://docs.python.org/3/glossary.html#term-hashable In short, if a class implements __hash__() (which should never change during an object's lifetime) and __eq__(), it can be hashable. Many python builtins are hashable, but mutable builtins aren't. For example lists aren't hashable. To investigate a bit further, we might examine a particular example more closely. In the code snippet that follows, we make two tuples with the same data and two instances of a user-defined class with the same data. We make a dictionary and see the difference between using tuples as keys and instances of a user-defined class as keys. ``` tup1 = (1, 2) tup2 = (1, 2) d = dict() d[tup1] = "one" print(d[tup2]) # prints "one" # Note that d "knows" tup1 and tup2 are "the same" class myclass: def __init__(self): self.data = [1, 2] myobj1 = myclass() myobj2 = myclass() print(myobj1.data == myobj2.data) # True d[myobj1] = "spam" print(d[myobj2]) # raises KeyError as myobj2 not in dictionary # d doesn't "know" that myobj1 and myobj2 are "the same" ``` This difference in behavior is due to the default __hash__ and __eq__ methods for myclass, which don't consider the attributes of each instance, whereas the hashing and comparison of tuples does consider the contents of the tuple. - DLD -- David Lowry-Duda <da...@lowryduda.com> <davidlowryduda.com> -- https://mail.python.org/mailman/listinfo/python-list