I understand that there are magic methods in python that can be overwritten by classes to control the way certain built in functions treat the members of these classes. For example, the behavior of len()
and str()
can be overwritten via magic methods __len__()
and __str__()
:
class EmptySet(object):
def __len__(self):
return 0
def __str__(self):
return '[]'
>>> e = EmptySet()
>>> str(e)
[]
>>> len(e)
0
There are also __cmp__()
and __ge__()
, __le__()
etc methods to control how these objects can be compared and how a list of them should be ordered by list.sort()
. My question is not about customizing the ordering of objects in a list but about sorting the object itself. Suppose the set weren't empty and I want to use sorted()
to sort it:
class SetOfTwo(object):
def __init__(self, a , b):
el_0 = a
el_1 = b
def __len__(self):
return 2
def __str__(self):
return '[{}, {}]'.format(el_0, el_1)
Is there a magic method I can implement to have sorted()
flip the elements if they aren't in order? I'm picturing the following behavior:
>>> s = SetOfTwo(2, 1)
>>> str(s)
[2, 1]
>>> t = sorted(s)
>>> str(t)
[1, 2]
>>> type(t)
>>> SetOfTwo
You should definitely read the official documentation of how to emulate container types. Basically a class supposed to work as a container (list, dict etc.) needs to implement methods to set or get members __getitem__()
, __setitem__()
and iterate over items __iter__()
and to get the number of items - method __len__()
. This is the minimum. But you can also add the ability to delete items and other operations.
The behaviour of sorted()
built-in function is to iterate over elements of your container and compare them using methods you mentioned __cmp__(), __ge__(), __le__()
which should be defined for items and not the container as you know already. Then a new list
instance is created with items sorted and this new instance is returned. You can pass it to the constructor of your custom container then or you can wriap sorted()
with a custom function which will return the desired class instance.
As some have said in the comments, sets are unordered but I don't think your question is really about sets.
Python uses the data model methods you mentioned, ge, le, and cmp to determine how a class behaves when sorted() is called on it. You can see how I try to call it here, but Python objects and asks me to implement <.
>>> class a(object):
... pass
...
>>> b = a()
>>> c = a()
>>> d = [b, c]
>>> sorted(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'a' and 'a'
Hope this helps. Aslo, as other people said, it's a good idea to subclass something in collections.abc. I'd read Item 28 in effective python that talks about this to get a good idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With