python - 一次重载多个运算符

pte*_*han 2 python operator-overloading

我有一个自定义类,我想重载几个artihmetic操作符,并想知道是否有办法避免必须单独写出每个代码.我无法找到任何不明确地逐个过载每个运算符的示例.

class Foo(object):
    a=0 

    def __init__(self, a):
        self.a=a            

    def __add__(self, other):
        #common logic here
        return Foo(self.a+other.a)

    def __sub__(self, other):
        #common logic here  
        return Foo(self.a-other.a)

    def __mul__(self, other):
        #common logic here
        return Foo(self.a*other.a)

#etc...
Run Code Online (Sandbox Code Playgroud)

逻辑稍微复杂一点,但常见的模式是每个运算符重载方法都包含一些相同的代码来检查操作是否允许,然后使用类成员构造一个操作.我想减少冗余代码.这有效:

class Foo(object):
    a=0 

    def __init__(self, a):
        self.a=a            

    def operate(self, other, operator):
        #common logic here
        a = constructOperation(self.a, other.a, operator)
        return Foo(a)

    def __add__(self, other):
        return self.operate(other, "+")

    def __sub__(self, other):       
        return self.operate(other, "-")     


def constructOperation(operand0, operand1, operator):
    if operator=="+": 
        return operand0 + operand1
    if operator=="-": 
        return operand0 - operand1
Run Code Online (Sandbox Code Playgroud)

但是像这样手动构建操作似乎有点愚蠢.这种方法是否有意义,或者这里有更好的方法吗?

Ant*_*ony 5

你可以通过反射和高阶函数来完成它,尽管这可能不适合继承.

import operator

def apply_a(func):
    def inner(self, other):
        return Foo(func(self.a, other.a))
    return inner

class Foo(object):
    def __init__(self, a=0):
        self.a = a

for name in ['__add__','__mul__','__sub__']:
    setattr(Foo, name, apply_a(getattr(operator, name)))
Run Code Online (Sandbox Code Playgroud)


NPE*_*NPE 5

我只想使用该operator模块:

import operator

class Foo(object):

    a=0 

    def __init__(self, a):
        self.a=a            

    def operate(self, other, op):
        #common logic here
        return Foo(op(self.a, other.a))

    def __add__(self, other):
        return self.operate(other, operator.add)

    def __sub__(self, other):       
        return self.operate(other, operator.sub)     
Run Code Online (Sandbox Code Playgroud)