I will give up all the reasons why this might be a bad idea, as per your request.
Is this a way to go or is there a better alternative?
No need to go with numpy when regular abs takes complex numbers and is much faster *. There is also convenient total_ordering in functools , which is well suited for such simple comparisons if you want to reduce the code (but it can be slower):
from functools import total_ordering @total_ordering class CustomComplex(complex): def __eq__(self, other): return abs(self) == abs(other) def __lt__(self, other): return abs(self) < abs(other)
(This is all the code you need.)
I want my package to transparently work with the built-in complex data type, as well as with numpy.complex. How can this be done elegantly without code duplication?
It automatically works when the correct argument is a normal complex (or any) number:
>>> CustomComplex(1+7j) < 2+8j True
But the best thing you can do if you want to use < operators, etc., and not functions. The complex type does not allow __lt__ to be set, and the TypeError is hard-coded.
If you want to make such comparisons in normal complex numbers, you must define and use your own comparison functions instead of the usual operators. Or just use abs(a) < abs(b) , which is clear and not very verbose.
* Dates of built-in abs and numpy.abs :
>>> timeit.timeit('abs(7+6j)') 0.10257387161254883 >>> timeit.timeit('np.abs(7+6j)', 'import numpy as np') 1.6638610363006592
otus
source share