[英]Overriding operators within functions
I want to define operators for a class instance within a class function, like so: 我想在类函数中为类实例定义运算符,如下所示:
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)
However, this doesn't seem to work - I feel like I'm missing something about how the operators -
, +
, etc, call these functions. 但是,这似乎不起作用-我感觉好像缺少关于运算符
-
, +
等如何调用这些函数的内容。 ie: 即:
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
in MyClass2, the behavior of __add__
will be different. 在MyClass2,行为
__add__
会有所不同。 Can anyone explain how they are different, and how to make the behavior of the operator methods in MyClass similar to MyClass2? 谁能解释它们的不同之处,以及如何使MyClass中的操作符方法的行为类似于MyClass2?
EDIT: Just to make clear why I'm trying to do this, here's _operation_wrapper
. 编辑:只是为了弄清楚为什么我要这样做,这是
_operation_wrapper
。 The class this is a method of is a "Spectrum" object, which has an X-axis and a Y-axis. 这是一个方法类,是“光谱”对象,具有X轴和Y轴。 The goal is to allow arithmetic on the Y axes, but only if the X axes match.
目的是允许在Y轴上进行算术运算,但前提是X轴匹配。 However, it is acceptable for them to match to, say, 1/5th of a pixel size, so I wanted to do more that pure 'exact' matching.
但是,它们可以匹配到像素大小的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
Special methods like __add__()
are looked up on the type of the object, not on the instance. 像
__add__()
这样的特殊方法是在对象的类型上查找的,而不是在实例上查找的。 So 所以
a + b
is roughly translated to 大致翻译成
type(a).__add__(a, b)
This means that setting __add__
on the instance does not do anything useful (except for making a.__add__(b)
work). 这意味着在实例上设置
__add__
不会做任何有用的事情(除了使a.__add__(b)
起作用)。
Your example is a bit incomplete, so I can't provide full working code. 您的示例有点不完整,因此我无法提供完整的工作代码。 You might be able to move the code from
_define_arithmetic_attributes()
to the class body and access self.threshold
from inside operation_wrapper()
. 您可能可以将代码从
_define_arithmetic_attributes()
移到类主体,并可以从operation_wrapper()
内部访问self.threshold
。
(Note that I don't get the point of the _arithmetic_threshold
property. Why don't you simply access self.threshold
itself?) (请注意,我
_arithmetic_threshold
属性的_arithmetic_threshold
。为什么不简单地访问self.threshold
本身?)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.