#๐Ÿ”’ Question on Classes

20 messages ยท Page 1 of 1 (latest)

steel sinew
#

Hi, I have a question regarding the classes. I understand that classes are hasbhable by default in python but not immutable. I am able to use class as a key in a dictionary. To my understanding dictionary keys needs to be immutable and hashable at the same time right? Below class is not immutable but it became a key, how is that?

class Example:

    def __init__(self, var):
        self.var = var

    def method1(self):
        return self.var


myobj = Example("some_string")
my_dict = {myobj: 2}```
little pilotBOT
#

@steel sinew

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

cyan dawn
#

e.g. try mutating myobj and then try to access the key in your dict

steel sinew
#

For instance a tuple is hashable and immutable but if you put a list inside a tuple it becomes in-eligible for dict key

my_tuple = (3, 4, [1,2]) #Cannot become a key we get
TypeError: unhashable type: 'list'```
How come this behaviour is not shown with above class
cyan dawn
old hull
#

Had to do some digging on this one, TIL. ๐Ÿ™‚
Dict keys must be hashable, meaning they must return the same value when hash(key) is used on it.
The underlying method that is run by the hash() built-in is the .__hash__() method on that object.

For a class, the default implementation of __hash__() is essentially id(obj) // 16.
Therefore, the class instance is hashable because the hash value is tied solely to its memory address.

#

!e

class Example:

    def __init__(self, var):
        self.var = var

    def method1(self):
        return self.var


myobj = Example("some_string")
print(id(myobj))
print(hash(myobj))
print(id(myobj) // 16)
little pilotBOT
old hull
#

this So, because hash() provides a value, it is usable as a dict key.
And its memory address does not change so long as the object sticks around.

cyan dawn
#

obviously then the problem* with using this as dict keys is two class instances with the exact same fields aren't considered the same key (a == b but hash(a) != hash(b)), which may lead to confusion

steel sinew
#

@old hull Hmm. This is something new. I never knew about this. So dict keys necessarily need to hashable but not necessarily be immutable

old hull
#

Correct. You would need to implement your own version of __hash__ on your class for that to work (for different equivalent instances to result in the same key).

weary scarab
#

mutability *does not* imply un-hashability

#

as long as part(s) of the object participating in the hashing logic are immutable, it's hashable

#

e.g., function objects: they are /very/ mutable, e.g., f.__defaults__ is writable after the definition, and will take effect

#

but all functions (be it def'ed or lambda'd) are hashable

#

their identity is considered in hashing; and /that/ is immutable so it works out

little pilotBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.