2012-11-22 56 views
3

假设我定义了一个类A,并且我不希望任何人在没有离开的情况下编写该类的不等式。为什么NotImplemented引发TypeError?

class A(): 
    def __ne__(self, other): 
     return NotImplemented 
print(A() != A()) 

但这打印出True并没有提出一个TypeError虽然我刻意“关闭”的!=操作?

回答

8

,所以你应该有一个看起来像这样的方法。

通常,Python会交换操作数;如果a != b结果为NotImplemented,则会尝试使用b != a。这也会失败,因为您在操作员的两侧使用相同的类型。对于!=运算符,Python将回退以比较它们的内存地址,并且它们不相同(两个单独的实例),因此返回False。

请参阅do_richcompare C function for details

如果这是您的预期结果,则必须手动筹集TypeError()

+0

3.x丰富的比较实现的简单性是一个值得欢迎的解决方案。在2.x中,不是调用'__ne__'两次,Python将其调用6次(当'PyObject_RichCompare'调用'slot_tp_richcompare'时,两次调用'try_rich_compare'尝试按正常顺序和交换顺序执行4次]。最后,它会在'default_3way_compare'中得到指针比较,因为必须转换为'uintptr_t'来支持排序。 – eryksun

+0

是的,在这个问题上看到'python-3.x'标签让我感到很放心。不得不详细说明在python 2中如何工作会导致*稍微*更长的答案。然而,我只按照LR,RL,RL,LR(用于左手和右手实例)的顺序,对'A()!= A()'计算'__ne__'的* 4 *调用次数。 –

-2

它给你真正的,因为你是返回一个例外,而不是它提高它。这意味着你正在返回一个非Null对象(例外)作为测试的结果。除非另有说明,否则非空对象评估为True。 请记住,除非您提出异常,否则这是一个普通对象。当您返回NotImplemented表明您不知道如果__ne__返回TrueFalse

class A(): 
    def __ne__(self, other): 
     raise NotImplementedError 
+2

不,它是*不是例外。阅读['__ne__']的文档(http://docs.python.org/3/reference/datamodel.html#object.__ne__);这是一个单身人士为此目的。 –

+0

的确,我正在考虑这个例外。不要误解我的意思,但是从这个意义上说文档是有缺陷的,因为NotImplemented的bool()返回True,并且不会给出任何有意义的错误。所以,正确的程序是引发一个例外,至少在OP的意图上(据我所知) – EnricoGiampieri

+0

不,'NotImplemented'是一个非常有用的哨兵值(也就是说,一个值表示在那里没有实现的东西)。 – delnan

相关问题