I want to implement the following functionality:
TestClass
values
accepts arbitrary number of NewClass
objectsNewClass
objects which do not have all the same attribute values get added to
TestClass.values
I've come up with this:
class NewClass:
def __init__(self, value1, value2):
self.value1 = value1
self.value2 = value2
class TestClass:
def __init__(self, *values):
self.values = self._set(values)
def _set(self, object_list):
unique_dict = {}
for obj in object_list:
if list(obj.__dict__.values()) not in unique_dict.values():
unique_dict[obj] = list(obj.__dict__.values())
return list(unique_dict.keys())
obj1 = NewClass(1, 2)
obj2 = NewClass(1, 2)
obj3 = NewClass(5, 2)
test = TestClass(obj1, obj2, obj3)
Only obj1
and obj3
are in the test.values
I am wondering how to do it in "protocol" way, such as len
or add
, etc.
def __len__(self):
return len(self.values)
And does the second approach have meaningful benefits compared to the first one?
Assuming your value1
and value2
are immutable (integers, strings and tuples are fine; lists and dicts are not), you can hash them -- implementing both __hash__
and __eq__
will allow the built-in set type to identify duplicates.
class NewClass:
def __init__(self, value1, value2):
self.value1 = value1
self.value2 = value2
def __hash__(self):
return hash((self.value1, self.value2))
def __eq__(self, other):
return self.value1 == other.value1 and self.value2 == other.value2
def __repr__(self):
return 'NewClass(%r, %r)' % (self.value1, self.value2)
print(set([NewClass(1,2), NewClass(1,2), NewClass(3,4)]))
...properly returns:
{NewClass(1, 2), NewClass(3, 4)}