There are no __min__ and __max__ special methods*. This is kind of a shame since range has seen some pretty nice optimizations in Python 3. You can do this:
>>> 1000000000000 in range(1000000000000)
False
But don't try this unless you want to wait a long time:
>>> max(range(1000000000000))
However creating your own min/max functions is a pretty good idea, as suggested by Lærne.
Here is how I would do it. UPDATE: removed the dunder name __min__ in favor of _min, as recommended by PEP 8:
Never invent such names; only use them as documented
Code:
from functools import wraps
oldmin = min
@wraps(oldmin)
def min(*args, **kwargs)
try:
v = oldmin(*args, **kwargs)
except Exception as err:
err = err
try:
arg, = args
v = arg._min()
except (AttributeError, ValueError):
raise err
try:
return v
except NameError:
raise ValueError('Something weird happened.')
I think this way is maybe a little bit better because it handles some corner cases the other answer hasn't considered.
Note that an iterable object with a _min method will still be consumed by oldmin as per usual, but the return value is overridden by the special method.
HOWEVER, if the _min method requires the iterator to still be available for consumption, this will need to be tweaked because the iterator is getting consumed by oldmin first.
Note also that if the __min method is simply implemented by calling oldmin, things will still work fine (even though the iterator was consumed; this is because oldmin raises a ValueError in this case).
* Such methods are often called "magic", but this is not the preferred terminology.