110

I would like to define my own operator. Does python support such a thing?

1
  • 1
    Well, you could have an operator which isn't defined (like $) and then use some python code to edit itself (with open) and change all a $ b to function(a,b) Commented Sep 29, 2017 at 3:04

6 Answers 6

220

While technically you cannot define new operators in Python, this clever hack works around this limitation. It allows you to define infix operators like this:

# simple multiplication
x=Infix(lambda x,y: x*y)
print 2 |x| 4
# => 8

# class checking
isa=Infix(lambda x,y: x.__class__==y.__class__)
print [1,2,3] |isa| []
print [1,2,3] <<isa>> []
# => True
Sign up to request clarification or add additional context in comments.

7 Comments

+1 That hack is pretty cool, but I don't think it will work in this situation.
It might be an intersting hack but i don't think that this is good solution. Python does not allow to create own operators, a design decision which was made for a good reason and you should accept it instead of seeing this as a problem and inventing ways around it. It is not a good idea to fight against the language you are writing the code in. If you really want to you should use a different language.
@DasIch I couldn't disagree more. We're not all free to chose a language deliberately. On the other side, I don't see why I should settle with anybody else's design decisions if I'm not satisfied. - Excellent hack indeed!
+1 For a very cool hack, but my question was more about whether defining my own operators is a feature in Python or not, not whether it's possible to fake having new operators, and it would seem the answer is no, you can't define new operators. Although this does come pretty darn close.
I just combined this with pipe from toolz. pip = Infix(lambda x,y: pipe(x,y)). then 8 |pip| range |pip| sum |pip| range. seems to work.
|
50

No, Python comes with a predefined, yet overridable, set of operators.

2 Comments

I'm curious to know how dfply uses a --> operator: towardsdatascience.com/…
@MaxCandocia As far as I can tell, it doesn’t (see docs). The example in that post that uses --> seems to be psuedocode. The library itself just overloads >>.
42

No, you can't create new operators. However, if you are just evaluating expressions, you could process the string yourself and calculate the results of the new operators.

1 Comment

See bellow for Python’s set of predefined overridable set of operators.
14

Sage provides this functionality, essentially using the "clever hack" described by @Ayman Hourieh, but incorporated into a module as a decorator to give a cleaner appearance and additional functionality – you can choose the operator to overload and therefore the order of evaluation.

from sage.misc.decorators import infix_operator

@infix_operator('multiply')
def dot(a,b):
    return a.dot_product(b)
u=vector([1,2,3])
v=vector([5,4,3])
print(u *dot* v)
# => 22

@infix_operator('or')
def plus(x,y):
    return x*y
print(2 |plus| 4)
# => 6

See the Sage documentation and this enhancement tracking ticket for more information.

Comments

14

Python 3.5 introduces the symbol @ for an extra operator.

PEP465 introduced this new operator for matrix multiplication, to simplify the notation of many numerical code. The operator will not be implemented for all types, but just for arrays-like-objects.

You can support the operator for your classes/objects by implementing __matmul__().

The PEP leaves space for a different usage of the operator for non-arrays-like objects.

Of course you can implement with @ any sort of operation different from matrix multiplication also for arrays-like objects, but the user experience will be affected, because everybody will expect your data type to behave in a different way.

3 Comments

Do you just mean that @ is a new operator symbol? Or that we can somehow use it to define new operators of our own?
Yes, @ is a new operator symbol. Yes, you can use it to define operations on your objects. Consider reading the PEP465.
@Addem He just meant that @ is a new operator. That's it. The fact still remains: You can't define operators of your own in Python.
13

If you intend to apply the operation on a particular class of objects, you could just override the operator that matches your function the closest... for instance, overriding __eq__() will override the == operator to return whatever you want. This works for almost all the operators.

1 Comment

Could you provide an example? I would (for example) like to replace the exponentiation operator ** with ^

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.