Is it possible to overload operators for Python functions? I have a bunch of functions taking two positional arguments and returning boolean type, e.g.
def both_positive(a, b):
return a > 0 and b > 0
def larger(a, b):
return a > b
def both_negative(a, b):
return a < 0 and b < 0
# ... many other similar functions
func = both_positive & larger # means logical and
# func = both_positive | larger # means logical or
# complex_customized_logic = both_positive | larger & either_float ...
assert func(3, 1) is True # 3 > 1, and both positive
assert func(2, -1) is False # 2 > -1, but -1 is negative
CodePudding user response:
It would be cleaner to call both functions like so:
both_positive(a, b) and larger(a, b)
both_positive(a, b) or larger(a, b)
Otherwise you can define a function that does this by calling the other two functions:
def both_positive_and_larger(a, b):
return both_positive(a, b) and larger(a, b)
CodePudding user response:
Python functions are "first-class objects", so you can write yourself a pair of functors to call them on your pair of arguments with the desired logic:
def all_true(*funcs):
return lambda a, b: all(f(a,b) for f in funcs)
def any_true(*funcs):
return lambda a, b: any(f(a,b) for f in funcs)
Then you can construct the example test you gave in your comment:
both_negative & smaller | larger & both_positive
like this:
>>> check = any_true(all_true(both_neg, smaller), all_true(larger, both_positive))
>>> check(-3, -1)
True
Not as readable as having infix operators, but at least you only need to pass the arguments once.
Note that you can pass any number of functions, not just two. And you could name your functors AND()
and OR()
instead of all_true()
and any_true()
if you find this more readable:
check = OR(AND(both_neg, smaller, distant), AND(larger, both_positive))