Reputation: 3191
I'd like to represent an object as a string so that it can be accessed both as a dictionary key and as an object in itself. i.e.
class test(object):
def __init__(self, name, number_array):
self.name = name
self.number_array = number_array
self.graph= barChart(number_array)
sample_obj = test('test_object', [(x1,y1), (x2,y2)etc.])
but so that {sample_obj: another_object}
would look like {'test_object': another_object}
while still making something like this possible:
for key, val in sample_dict.items(): print(key.name, key.graph)
as well as:
>>> sample_dict['test_object']
another_object
Upvotes: 0
Views: 310
Reputation: 1047
You must define eq that returns positive when comparing with the string i.e.:
def __eq__(self, other):
if self.name == other:
return True
... continue with comparison ...
You must also define hash that returns the same hash as the compared string:
def __hash__(self):
return hash(self.name)
UPDATE: The following code does exactly what the author wanted:
class test(object):
def __init__(self, name, number_array):
self.name = name
self.number_array = number_array
#self.graph= barChart(number_array)
def __eq__(self, other):
try:
return (self.name == other.name) and (self.number_array == other.number_array)
except AttributeError:
return self.name == other
def __hash__(self):
return hash(self.name)
sample_obj = test('test_object', [(0, 1), (2, 3)])
dict1 = {sample_obj: "Hurray"}
print("dict1[sample_obj]", dict1[sample_obj])
print("dict1['test_object']", dict1['test_object'])
dict2 = {'test_object': "Yippie"}
print("dict2[sample_obj]", dict2[sample_obj])
print("dict2['test_object']", dict2['test_object'])
Upvotes: 1
Reputation: 122007
To use a class as a dictionary key, implement __hash__
and __eq__
. To change how it appears when you print the dictionary, implement __repr__
:
class Test(object):
def __init__(self, name, number_array):
self.name = name
self.number_array = number_array
self.graph = barChart(number_array)
def __eq__(self, other):
return self.name == other.name and self.number_array == other.number_array
def __hash__(self):
return hash(self.name) ^ hash(self.number_array)
def __repr__(self):
return "test_object"
In use:
>>> t = Test("foo", (1, 2, 3))
>>> d = {t: [1, 2, 3]}
>>> t
test_object
>>> d
{test_object: [1, 2, 3]}
>>> d[t]
[1, 2, 3]
Note that this means that both the name
and number_array
attributes must be hashable - I have used a string and a tuple to ensure this. Also, it is better if __repr__
represents the actual object more closely, e.g.
def __repr__(self):
return "Test({0.name!r}, {0.number_array!r})".format(self)
Upvotes: 1