Search code examples
pythonpython-3.xmagic-methods

Is there a way to return a custom value for min and max in Python?


I have a custom class,

class A:
    def __init__(self, a, b):
        self.a = a
        self.b = b

The class is not iterable or indexable or anything like that. If at all possible, I would like to keep it that way. Is it possible to have something like the following work?

>>> x = A(1, 2)
>>> min(x)
1
>>> max(x)
2

What got me thinking about this is that min and max are listed as "Common Sequence Operations" in the docs. Since range is considered to be a sequence type by the very same docs, I was thinking that there must be some sort of optimization that is possible for range, and that perhaps I could take advantage of it.

Perhaps there is a magic method that I am not aware of that would enable this?


Solution

  • Yes. When min takes one arguments it assumes it to be an iterable, iterates over it and takes the minimum value. So,

    class A:
        def __init__(self, a, b):
            self.a = a
            self.b = b
        def __iter__(self):
            yield self.a
            yield self.b
    

    Should work.

    Additional Note: If you don't want to use __iter__, I don't know of way to do that. You probably want to create your own min function, that calls some _min_ method if there is one in the argument it is passed to and calls the old min else.

    oldmin = min
    def min(*args):
        if len(args) == 1 and hasattr(args[0], '_min_'):
            return args[0]._min_()
        else:
            return oldmin(*args)