Python 重写函数中的运算符

Python 重写函数中的运算符,python,overriding,Python,Overriding,我想在类函数中为类实例定义运算符,如下所示: class MyClass(object): @property def _arithmetic_threshold(self): return self.threshold # this will be defined somewhere @_arithmetic_threshold.setter def _arithmetic_threshold(self,value): sel

我想在类函数中为类实例定义运算符,如下所示:

class MyClass(object):

    @property
    def _arithmetic_threshold(self):
        return self.threshold # this will be defined somewhere

    @_arithmetic_threshold.setter
    def _arithmetic_threshold(self,value):
        self.threshold = value
        self._define_arithmetic_attributes()

    def _define_arithmetic_attributes(self):
        """
        Wrapper to define all arithmetic attributes (in order to allow threshold changes)
        """

        self.__add__ = self._operation_wrapper(np.add,threshold=self._arithmetic_threshold)
        self.__sub__ = self._operation_wrapper(np.subtract,threshold=self._arithmetic_threshold)
        self.__mul__ = self._operation_wrapper(np.multiply,threshold=self._arithmetic_threshold)
        self.__div__ = self._operation_wrapper(np.divide,threshold=self._arithmetic_threshold)
但是,这似乎不起作用-我觉得我缺少了一些关于操作符
-
+
等如何调用这些函数的信息。i、 e:

class MyClass2(object):
    def __add__(self,other,threshold=None):
        if threshold is not None:
            return self+other
        else:
            # do something here involving checking a threshold....
            pass
在MyClass2中,
\uuuuuuuuuuuuuuuuuuuuuuu
的行为将不同。谁能解释一下它们之间的区别,以及如何使MyClass中的运算符方法的行为类似于MyClass2

编辑:为了弄清楚我为什么要这么做,下面是
\u operation\u wrapper
。这是一个类的方法是一个“光谱”对象,它有一个X轴和一个Y轴。目标是允许在Y轴上进行算术运算,但前提是X轴匹配。然而,它们可以匹配到,比如说,像素大小的1/5,所以我想做更多纯粹的“精确”匹配

def _operation_wrapper(operation):
    """
    Perform an operation (addition, subtraction, mutiplication, division, etc.)
    after checking for shape matching
    """

    def ofunc(self, other): 
        if np.isscalar(other):
            newspec = self.copy()
            newspec.data = operation(newspec.data, other) 
            return newspec
        else: # purely for readability

            if self._arithmetic_threshold == 'exact':
                xarrcheck = all(self.xarr == other.xarr)
            else:
                if self._arithmetic_threshold_units is None:
                    # not sure this should ever be allowed
                    xarrcheck = all((self.xarr-other.xarr) < self._arithmetic_threshold)
                else:
                    xarrcheck = all((self.xarr.as_unit(self._arithmetic_threshold_units)-other.xarr.as_unit(self._arithmetic_threshold_units)) < self._arithmetic_threshold)

            if self.shape == other.shape and xarrcheck:
                newspec = self.copy()
                newspec.data = operation(newspec.data, other.data)
                return newspec
            elif self.shape != other.shape:
                raise ValueError("Shape mismatch in data")
            elif not xarrcheck:
                raise ValueError("X-axes do not match.")

    return ofunc
def\u操作\u包装(操作):
"""
执行操作(加法、减法、乘法、除法等)
检查形状匹配后
"""
def ofunc(自身、其他):
如果np.isscalar(其他):
newspec=self.copy()
newspec.data=操作(newspec.data,其他)
返回新闻规格
否则:#纯粹为了可读性
如果self.\u算术\u阈值==“精确”:
xarrcheck=all(self.xarr==other.xarr)
其他:
如果self.\u算术\u阈值\u单位为无:
#我不确定这是否应该被允许
xarrcheck=all((self.xarr-other.xarr)
\uuuu add\uuuu()
这样的特殊方法是在对象的类型上查找的,而不是在实例上。所以

a + b
大致翻译为

type(a).__add__(a, b)
这意味着在实例上设置
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
没有任何用处(除了使
a.\uuuuuuuuuuuuuuuuuuuuu

您的示例有点不完整,因此我无法提供完整的工作代码。您可以将代码从
\u define\u算术\u attributes()
移动到类主体,并从
操作包装器()内部访问
self.threshold


(请注意,我没有理解
\u算术\u threshold
属性的要点。为什么不直接访问
self.threshold
本身?

关于
属性的好问题
-我已经更新了示例,以演示我的意图。有没有更好的方法来做我正在做的事情?i、 例如,是否根据阈值重新设置
\uuuuu添加\uuuu
方法?我真正想做的是,仅当两个实例的某些属性(光谱的X轴…)在某个阈值范围内时,才允许在两个实例之间进行算术运算,否则会在retrospect中引发异常,您关于访问
self.threshold
内部
operation\u wrapper
的评论可能是一个不错的选择。@keflavich:为了给您提供更多信息,我需要知道
\u operation\u wrapper()
是什么样子。可能有一种完全不同的方法。有关高级(而且很酷)的操作符重写示例,请参阅我在上面提出的一个问题的精彩答案。