我有一个小助手班:
class AnyOf(object):
def __init__(self, *args):
self.elements = args
def __eq__(self, other):
return other in self.elements
这让我可以做出如下的甜蜜魔法:
>>> arr = np.array([1,2,3,4,5])
>>> arr == AnyOf(2,3)
np.array([False, True, True, False, False])
无需使用列表推导(如np.array(x in (2,3) for x in arr
)。
(我维护一个让(可信)用户输入任意代码的用户界面,a == AnyOf(1,2,3)
比非技术精明用户的列表理解更可口。)
然而!
这只适用于一种方式!例如,如果我要执行AnyOf(2,3) == arr
,那么我的AnyOf
类的__eq__
方法永远不会被调用:相反,NumPy数组的__eq__
方法被调用,内部(我会presume)调用其所有元素的__eq__
方法。
这让我想知道:为什么Python不允许右侧等同于__eq__
? (大致相当于__radd__
,__rmul__
等方法。)
答案 0 :(得分:5)
import os
os.system('CLS')
user_input = ''
while user_input != 'quit':
user_input = input('Input something:')
os.system('CLS') # Clear the console.
# On Unix systems you have to use 'clear' instead of 'CLS'.
# os.system('clear')
在该语言中不是一个好主意,因为如果类__req__
定义Left
而类__eq__
定义Right
,那么Python就有义务在__req__
中做出关于谁首先被召唤的一致决定。他们无法获胜。
但是,Python数据模型确实允许您在此处执行所需操作。从两侧您可以控制此比较,但您需要正确定义Left() == Right()
。 如果您希望AnyOf
从右侧控制__eq__,则必须将其定义为AnyOf
的子类。
如果我要
np.ndarray
,那么我的AnyOf(2,3) == arr
课程AnyOf
方法永远不会被调用
不,你在这里有一个根本的误解。除非右侧是左侧类型的子类,否则左侧总是首先尝试相等比较。
__eq__
在上面的情况中,您的自定义arr == AnyOf(2,3)
被调用,因为numpy数组会调用它!所以__eq__
获胜,并决定每个元素检查一次。它确实可以做任何其他事情,包括根本不打电话给你np.ndarray
。
AnyOf.__eq__
在上面的例子中,你的类确实在比较时首次尝试,并且由于你使用AnyOf(2,3) == arr
的方式(检查数组是否在元组中)而失败。
答案 1 :(得分:2)
关于__radd__
方法的documentation __add__
州:
仅当左操作数不支持时才调用这些函数 相应的操作和操作数是不同类型的。
虽然每个默认类没有__sub__
或__eq__
方法,但执行有>>> class A(object):
... pass
>>> '__eq__' in dir(A)
True
:
__req__
这意味着永远不会调用__eq__
,除非您从其他类中明确删除np.in1d
。
您可以使用>>> np.in1d(arr, [2, 3])
array([False, True, True, False, False], dtype=bool)
解决您的具体问题:
{{1}}
答案 2 :(得分:1)
这是data model上的文档:
这些方法没有交换参数版本(当左参数不支持操作但是支持时使用 正确的论据确实);相反,
__lt__()
和__gt__()
是彼此的 反射,__le__()
和__ge__()
是彼此的反映,和__eq__()
和__ne__()
是他们自己的反映。如果操作数是不同类型的,则右操作数的类型是直接或间接的 左操作数类型的子类,右侧的反射方法 操作数有优先级,否则左操作数的方法有 优先。不考虑虚拟子类化。
如上面的评论中所述,您想要的是什么,__eq__
与潜在的__req__
基本相同:如果==
在NotImplemented
的右侧调用它左侧的对象返回In [1]: class A:
...: def __eq__(self, other):
...: return NotImplemented
...:
In [2]: class B:
...: def __eq__(self, other):
...: print("B comparing")
...: return True
...:
In [3]: B() == A()
B comparing
Out[3]: True
In [4]: A() == B()
B comparing
Out[4]: True
In [5]: A() == A()
Out[5]: False
:
In [10]: 5 == B()
B comparing
Out[10]: True
实际上,它甚至可以与其他普通对象一起使用:
__eq__
但是,某些对象可能会在NotImplemented
上产生TypeError,而不是返回False
或in
,这使得这对所有类型的对象都不可靠。
在您的情况下发生的情况是,在您自己的__eq__
方法中使用数组和元组的运算符<div id="fullpage">
<div class="section">One</div>
<div class="section">Two</div>
<div id="three" class="section">Three</div>
<div id="four" class="section fp-normal-height fp-normal-scroll">
<div style="height:1000px;">Four</div>
</div>
</div>
<footer style="height:300px;">Site footer</footer>
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
hybrid:true,
fitToSection: false,
afterLoad: function(anchorLink, index){
var loadedSection = $(this);
if(loadedSection.attr("id") == "four") {
$.fn.fullpage.setAutoScrolling(false);
}
if(loadedSection.attr("id") == "three") {
$.fn.fullpage.setAutoScrolling(true);
}
},
});
是错误的。 (感谢@wim在这里的另一个答案中发现了这一点。)