HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Class for simple python object to be hashed and referenced

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simplereferencedhashedpythonforandobjectclass

Problem

I need objects in python that I can compare, reference to and hash.

In principal a tuple or list would be good enough just that
a list I cannot hash and the tuple I cannot change,
except replacing it which means losing references to it.

So I created a class for it, but still have the feeling there should be a simpler/better solution to it.

class MyClass:
    def __init__(self, k, l=0, m=0):
        self.k = k
        self.l = l
        self.m = m
    def __hash__(self):
        n_attr = len(self.__dict__)
        return sum(hash(attr)/n_attr for attr in self.__dict__.values())
    def __eq__(self, other):
        return all(sa==oa for sa, oa in zip(self.__dict__.values(),
                                           other.__dict__.values()))


Now I can do what I need: creating some objects

x = MyClass(1,2,3)
y = MyClass(7)
z = MyClass(7,1,0)


and some references

a = x; b = y; c = y; d = z


and compare, manipulate ...

b == c # True
b == d # False
b.l = 1
b == c # still True
b == d # now True
s = {a, d, (a,b)}
b in s # True
c in s # True
(a,c) in s # True


I wished I could just forget about the class and do

x = 1,2,3
y = 7,
z = 7,1


etc ...

Is writing this class the best way to approach this problem? Or did I miss something?

edit:

After the comment by WinstonEwert I confirmed that the objects cause breakage as keys in dictionary

s = {a: 'a', b: 'b'}
s[c] # 'b'
c.l = 99
s[c] # key error
s # key error


and decided to replace dictionaries that use these objects as keys by

```
class MyDict:
def __init__(self, d={}):
self._data = d.items()
def __getitem__(self, key):
for k, v in self._data:
if k == key: return v
raise KeyError
def __setitem__(self, key, value):
for i, (k, v) in enumerate(self._data):
if k == key:
self._data[i] = key, value
return
self._data.append((key,value))
def __contains__(self, key):

Solution

The python dictionary assumes that the keys are immutable. It assumes they will not change. That's why mutable classes in python (such as lists) don't hash. Its to prevent you from putting them in dicts which just won't work.

As a result the entire premise of your class is wrong. You shouldn't do that. To follow what python expects, an object should return the same hash and be equal to the same objects throughout its lifetime. If it can't it shouldn't support hashing.

We might be able to suggest a better way to do this, but you'll need to show more of how you want to use this class.

Context

StackExchange Code Review Q#26008, answer score: 4

Revisions (0)

No revisions yet.