Python:定义自己的运算符?


79

我想定义自己的运算符。python支持这样的事情吗?


好吧,您可能有一个未定义的运算符(如$),然后使用一些python代码进行自我编辑(带有open),然后全部更改a $ bfunction(a,b)
whackamadoodle3000 17/09/29

Answers:


40

不,您不能创建新的运算符。但是,如果您只是在评估表达式,则可以自己处理字符串并计算新运算符的结果。


1
有关Python的一组预定义的可覆盖运算符集,请参见下面的内容。
Palimondo '17

179

从技术上讲,您无法在Python中定义新的运算符,但这种巧妙的技巧可解决此限制。它允许您定义如下中缀运算符:

# 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

2
+1骇客非常酷,但我认为在这种情况下不会起作用。
2009年

9
这可能是一个有趣的hack,但我认为这不是一个好的解决方案。Python不允许创建自己的运算符,这是出于充分的理由而做出的设计决策,您应该接受它,而不是将其视为问题并提出解决方法。与编写代码的语言作斗争不是一个好主意。如果确实需要,则应使用其他语言。
DasIch 2009年

78
@DasIch我完全不同意。我们并非全都自由地选择一种语言。另一方面,如果我不满意,我不明白为什么我应该接受其他人的设计决定。-确实很棒!
ThomasH

+1对于一个非常酷的黑客,但我的问题更多是关于定义自己的运算符是否是Python的功能,而不是是否可以假冒拥有新的运算符,而且看来答案是否定的,您不能定义新的运算符。尽管这确实非常接近。
ArtOfWarfare 2014年

2
我只是将其与pipefrom相结合toolzpip = Infix(lambda x,y: pipe(x,y))。然后8 |pip| range |pip| sum |pip| range。似乎有效。
cantdutchthis 2015年


11

Sage提供了此功能,基本上使用了@Ayman Hourieh所描述的“聪明的技巧”,但作为装饰器并入模块中,以提供更整洁的外观和其他功能-您可以选择要重载的运算符,从而选择评估顺序。

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

有关更多信息,请参见Sage文档此增强跟踪票证


10

如果打算将操作应用于特定的对象类,则可以覆盖与您的函数最接近的运算符...例如,覆盖__eq__()将覆盖==运算符以返回所需的任何内容。这几乎适用于所有运营商。


9

Python 3.5引入了@用于额外运算符的符号。

PEP465引入了这种用于矩阵乘法的新运算符,以简化许多数字代码的表示法。不会为所有类型实现该运算符,而只会为类似于数组的对象实现。

您可以通过实现来支持您的类/对象的运算符__matmul__()

PEP为类似非数组的对象留出空间供操作员不同使用。

当然,@对于类似于数组的对象,您也可以使用不同于矩阵乘法的任何类型的操作来实现,但是用户体验会受到影响,因为每个人都希望您的数据类型以不同的方式运行。


您只是说这@是一个新的运算符符号吗?还是我们可以以某种方式使用它来定义我们自己的新运算符?
Addem '16

是的,@是新的运算符。是的,您可以使用它来定义对对象的操作。考虑阅读PEP465。
gg349 '16

5
@Addem他只是说这@是一个新运算符。而已。事实仍然存在:您无法在Python中定义自己的运算符。
约翰·雷德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.