Python: defining my own operators?
Asked Answered
W

6

110

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

Wreckful answered 31/5, 2009 at 16:1 Comment(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)Doerrer
H
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.

Heartsome answered 31/5, 2009 at 16:6 Comment(1)
See bellow for Python’s set of predefined overridable set of operators.Viole
H
218

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
Helli answered 31/5, 2009 at 18:18 Comment(7)
+1 That hack is pretty cool, but I don't think it will work in this situation.Heartsome
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.Rochdale
@Rochdale 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!Kopje
+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.Disincline
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.Duvall
Note that this hack limits you to the hard-coded precedence and associativity of the standard operators it abuses.Riga
Interesting solution, but perhaps what still makes it a bit inferior to actually defining an operator (which is impossible in Python without preprocessing of your code) is that you don’t have access the arguments before they’re evaluated. You can therefore not e. g. define your own assignment operator or control evaluation order like the and operator.Overprint
K
50

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

Krantz answered 31/5, 2009 at 16:3 Comment(2)
I'm curious to know how dfply uses a --> operator: towardsdatascience.com/…Uraemia
@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 >>.Xylon
H
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.

Heartsome answered 31/5, 2009 at 16:6 Comment(1)
See bellow for Python’s set of predefined overridable set of operators.Viole
B
15

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.

Boohoo answered 9/1, 2015 at 10:32 Comment(3)
Do you just mean that @ is a new operator symbol? Or that we can somehow use it to define new operators of our own?Surrender
Yes, @ is a new operator symbol. Yes, you can use it to define operations on your objects. Consider reading the PEP465.Boohoo
@Surrender 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.Hemimorphic
T
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.

Tjaden answered 18/12, 2013 at 19:47 Comment(0)
R
12

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.

Ranchero answered 31/5, 2009 at 16:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.