2

I am writing a test utility to make assertions with pandas Series easier. For example I would like to be able to write assert my_series == Constant(3) to check that all the elements of the Series are equal to 3. To do so I have created a class Constant redefining the comparison operators :

import pandas as pd

class Constant:
    
    def __init__(self, value):
        self._value = value
    
    def __eq__(self, other: pd.Series):
        return (other == self._value).all()

But depending on the operand order, my comparison implementation is not always used by Python :

s = pd.Series([3]*10)

print("Constant(3) == s :")
print(Constant(3) == s)   # GOOD : Constant.__eq__ is called

print("s == Constant(3)")
print(s == Constant(3))   # BAD : Series.__eq__ is called

According to this answer I could solve this by defining Constant as a subclass of Series. But if I want Constant to work with several array-like types I have to make it inheriting from Series, DataFrame, ndarray etc... It would make a very strange object with a lot of useless attributes and methods.

What is the best solution ? For example, is there a way to add several array-like types as base classes of Constant and then remove all the inherited elements ?

nocibor
  • 69
  • 5
  • 3
    Technical solutions aside, I think any equality test should always be commutative. If this can't hold true, it may be a good idea to just create a separate function `compare_constants(a, b)` and do custom comparison in it. – ernest_k Jan 28 '22 at 10:24
  • 1
    @ernest_k I believe Python designers believe that too, hence why we don't have `__req__` – DeepSpace Jan 28 '22 at 10:26
  • Of course, a function would definitely do the job. But for readability reasons I would use this solution as a last resort. – nocibor Jan 28 '22 at 10:30
  • 1
    @nocibor I doubt that it's a good idea. Semantically, `Constant(3)` is not equivalent to `s`. – Expurple Jan 28 '22 at 10:30
  • @DeepSpace I would use `pandas.testing` internaly. My purpose is to ensure the best readability for non-technical users. – nocibor Jan 28 '22 at 10:34
  • @Expurple To be more precise, all my `Series` represent signal evolutions over time. In that case `s == Constant(3)` make sense to my mind. – nocibor Jan 28 '22 at 10:42
  • 1
    `numpy` has an `__array_priority__` that allows `ndarray` subclasses to control the operation. – hpaulj Jan 28 '22 at 17:00

0 Answers0