Python中的新运算符

Python中的新运算符,第1张

Python中的新运算符

扩展@fasouto答案,但添加更多代码。

虽然您不能定义新的运算符,也不能为内置类型重新定义现有的运算符,但是您可以做的是定义一个类(实例化为任何有效的Python名称

op
),该类充当两个对象的中间绑定,从而有效地查找像二进制中缀运算符一样:

a | op | b
非约束性实施

总之,可以定义一个类中重写 向前向后 *** 作员,例如使用的方法

__or__
__ror__
用于
|
*** 作者:

class Infix:    def __init__(self, function):        self.function = function    def __ror__(self, other):        return Infix(lambda x, self=self, other=other: self.function(other, x))    def __or__(self, other):        return self.function(other)    def __call__(self, value1, value2):        return self.function(value1, value2)

可以直接使用:

op = Infix(lambda a, b: a + b)  # can be any bivariate function1 | op | 2# 3

或作为装饰者:

@Infixdef op(a, b):    return a + b1 | op | 2# 3

上述解决方案工作方式是,但也存在一些问题,如

op | 2
表达不能用 单纯

op = Infix(lambda a, b: a + b)(1 | op)#<__main__.Infix object at 0x7facf8f33d30># op | 2# TypeError: <lambda>() missing 1 required positional argument: 'b'1 | op | 2)# 3

绑定实现

为了获得适当的绑定,需要编写一些更复杂的代码来执行中间 绑定

class Infix(object):    def __init__(self, func):        self.func = func    class RBind:        def __init__(self, func, binded): self.func = func self.binded = binded        def __call__(self, other): return self.func(other, self.binded)        __ror__ = __call__    class LBind:        def __init__(self, func, binded): self.func = func self.binded = binded        def __call__(self, other): return self.func(self.binded, other)        __or__ = __call__    def __or__(self, other):        return self.RBind(self.func, other)    def __ror__(self, other):        return self.LBind(self.func, other)    def __call__(self, value1, value2):        return self.func(value1, value2)

使用方法与以前相同,例如:

op = Infix(lambda a, b: a + b)

或作为装饰者:

@Infixdef op(a, b):    return a + b

有了这个,就会得到:

1 | op# <__main__.Infix.LBind object at 0x7facf8f2b828>op | 2# <__main__.Infix.RBind object at 0x7facf8f2be10>1 | op | 2# 3

还有一个PyPI软件包,基本上实现了此功能:https :
//pypi.org/project/infix/

时机

顺便说一句,绑定解决方案似乎也快一些:

%timeit [1 | op | 2 for _ in range(1000)]# Non-binding implementation# 1000 loops, best of 3: 626 µs per loop# Binding implementation# 1000 loops, best of 3: 525 µs per loop
笔记

这些实现使用

|
,但是可以使用任何二进制运算符:

  • +
    __add__
  • -
    __sub__
  • *
    __mul__
  • /
    __truediv__
  • //
    __floordiv__
  • %
    __mod__
  • **
    __pow__
  • @
    :(
    __matmul__
    适用于Python 3.5及更高版本)
  • |
    __or__
  • &
    __and__
  • ^
    __xor__
  • >>
    __rshift__
  • <<
    __lshift__

**
需要绑定实现或调整非绑定实现以反映 *** 作符是 右关联的 。从上面的所有其他运营商要么 左结合
-
/
//
%
@
>>
<<
),或直接交换(
+
*
|
&
^
)。

请记住,它们都将具有与普通Python运算符相同的优先级,因此,例如:

(1 | op | 2 * 5) == (1 | op | (2 * 5)) != ((1 | op | 2) * 5)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5648402.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存