I have a current implementation like this:
class Infix(object):
def __init__(self, func):
self.func = func
def __or__(self, other):
return self.func(other)
def __ror__(self, other):
return Infix(partial(self.func, other))
def __call__(self, v1, v2):
return self.func(v1, v2)
@Infix
def Map(data, func):
return list(map(func,data))
This is great, it works as expected, however I want to also expand this implementation to allow for a left side only solution. If somebody can showcase a solution AND explanation, that would be phenomenal.
Here is an example of what I would like to do...
valLabels['annotations'] \
|Map| (lambda x: x['category_id']) \
|Unique|
Where Unique is defined as below...
@Infix
def Unique(data):
return set(data)
Thanks!
If you don't mind dropping the final |, you could do
class InfixR(object):
def __init__(self, func):
self.func = func
def __ror__(self, other):
return self.func(other)
def __call__(self, v1):
return self.func(v1)
@InfixR
def Unique(data):
return set(data)
Then your expression would look like
valLabels['annotations'] \
|Map| (lambda x: x['category_id']) \
|Unique
Your original Infix class is (technically) abusing the bitwise or operator: |Map| is nothing special, it's just value | Map | my_lambda, a "bitwise or" of a list, an object, and a lambda, with a couple of spaces removed, and some newlines inserted (using \ to prevent the interpretter from trying to treat each line separately).
In custom classes, you can implement many of the usual operators using __double_underscore__ methods, in the case of bitwise or, they are __or__ and __ror__.
When the python interpreter encounters the | operator, it first looks at the object to the right, to see if it has a __or__ method. It then calls left.__or__(right). If that is not defined or returns NotImplemented, it looks at the object on the right, for __ror__ (reversed or), and calls right.__ror__(left).
The other part of this is the decorator notation.
When you say
@Infix
def Unique(data):
return set(data)
The interpretter expands that into
def Unique(data):
return set(data)
Unique = Infix(Unique)
So you get an Infix instance, which has __or__ and __ror__ methods, and a __call__ method. As you might guess, my_obj.__call__() is called when you invoke my_oby().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With