In this case it is 50-50. If there was no consistency improvement I would not propose this, but I found that such consistency was required to make functionality of deferred evaluation graph objects complete in functionality.
One case that I needed this was custom object validators:
class ValidObject:
...
valid_obj = ValidObject()['a'].not_in([0, 1, 2])
obj1 = dict(a=1)
obj2 = dict(a=3)
valid_obj.is_valid(obj1) # False
valid_obj.is_valid(obj2) # True
Now obviously contains
can be used to implement this:
class ValidObject:
def not_in(self, other):
operator.contains(other, self)
But I don’t write these manually. I use mixin for adding a set of required functionality (similarly to how dask
does it), where I have operation specifications that are added to object automatically:
class ValidObject(MethodMixin):
_methods_to_add = [NOT_IN_METHOD, SUB_METHOD]
SUB_METHOD = Namespace(name='__sub__', func=operator.sub)
NOT_IN_METHOD = Namespace(name='not_in', func=operator.not_in)
There is no such issue with reversal of numeric methods, as:
valid_obj = 1 - ValidObject()
Will correctly swap arguments.
BTW, there was a suggestion regarding rev
methods for other functions Reversed ops in operator module - #2 by tjreedy. I have never needed any of those in practice.