我想在类函数中定义类实例的运算符,如下所示:
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)
但是,这似乎不起作用 - 我觉得我错过了关于运算符-
,+
等如何调用这些函数的内容。即:
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中,__add__
的行为会有所不同。任何人都可以解释它们是如何不同的,以及如何使MyClass中的运算符方法的行为类似于MyClass2?
编辑:只是为了说明我为什么要这样做,这里是_operation_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
答案 0 :(得分:6)
在对象的类型上查找__add__()
等特殊方法,而不是在实例上。所以
a + b
大致翻译为
type(a).__add__(a, b)
这意味着在实例上设置__add__
没有做任何有用的事情(使a.__add__(b)
工作除外)。
您的示例有点不完整,因此我无法提供完整的工作代码。您可以将代码从_define_arithmetic_attributes()
移至类主体,并从self.threshold
内访问operation_wrapper()
。
(请注意,我不明白_arithmetic_threshold
属性。你为什么不直接访问self.threshold
?)