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?
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)