Detailed Python built NotImplemented type of usage

What is it?
 

?
1
2
>>> type (NotImplemented)
< type 'NotImplementedType' >

NotImplemented is one constant in the built-in Python six namespace. Other False , True , None , Ellipsis and __debug__. And Ellipsis like, NotImplemented be re-assignment (covered). Assigned to it, and even change the attribute name, no SyntaxError. So it's not really a "true" constant. Of course, we should never change it. But for completeness:
 

?
1
2
3
4
5
6
7
8
>>> None = 'hello'
...
SyntaxError: can't assign to keyword
>>> NotImplemented
NotImplemented
>>> NotImplemented = 'do not'
>>> NotImplemented
'do not'

what's it for? When to use?

NotImplemented is a special value, it can be returned two yuan special methods (such __eq __ () , __lt __ ()  , __add __ () , __rsub __ (), etc.), indicating a type that does not perform the operations, as other types. Similarly two yuan special method, it may be treated in situ (in place) return (such __imul __ (), __ iand __ () , etc.). Also, its actual value is True:
 

?
1
2
>>> bool (NotImplemented)
True

You may be asking yourself, "But I think when this operation is not achieved, I should produce a NotImpementedError ." We will look at some examples about why the child is not the case when two yuan special methods.

Let's look at NotImplemented usage constant, by __eq __ () for two very basic (and useless) coding classes A and B, respectively. [For this simple example, in order to avoid interference, will not achieve __ne __ () , but in general, each time to achieve __eq __ () when, __ne __ () should also be achieved unless there is a sufficient enough reason to not Realize it. ]
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# example.py
  
class A( object ):
   def __init__( self , value):
     self .value = value
  
   def __eq__( self , other):
     if isinstance (other, A):
       print ( 'Comparing an A with an A' )
       return other.value = = self .value
     if isinstance (other, B):
       print ( 'Comparing an A with a B' )
       return other.value = = self .value
     print ( 'Could not compare A with the other class' )
     return NotImplemented
  
class B( object ):
   def __init__( self , value):
     self .value = value
  
   def __eq__( self , other):
     if isinstance (other, B):
       print ( 'Comparing a B with another B' )
       return other.value = = self .value
     print ( 'Could not compare B with the other class' )
     return NotImplemented

Now, in the interpreter:
 

?
1
2
3
>>> from example import A, B
>>> a1 = A( 1 )
>>> b1 = B( 1 )

我们现在可以实验下对于 __eq__() 不同的调用,看看发生了什么。作为提醒,在Python中,a == b会调用a.__eq__(b):
 

?
1
2
3
>>> a1 = = a1
Comparing an A with an A
True

正如所望,a1等于a1(自己),使用类A中的__eq__()来进行这个比较的。比较b1和它自己也会产生类似结果:
 

?
1
2
3
>>> b1 = = b1
Comparing a B with another B
True

现在,那要是我们比较a1和b1呢?由于在A的__eq__()会检查other是不是B的一个实例,我们想要a1.__eq__(b1)去处理这个比较并返回True:
 

?
1
2
3
>>> a1 = = b1
Comparing an A with a B
True

就是这样。现在,如果我们比较b1和a1(即调用b1.__eq__(a1)),我们会想要返回NotImplemented。这是因为B的__eq__()只和其他B的实例进行比较。来看看发生了什么:
 

?
1
2
3
4
>>> b1 = = a1
Could not compare B against the other class
Comparing an A with a B
True

聪明!b1.__eq__(a1)方法返回NotImplemented,这样会导致调用A中的__eq__()方法。而且由于在A中的__eq__()定义了A和B之间的比较,所以就得到了正确的结果(True)。

这就是返回了NotImplemented的所做的。NotImplemented告诉运行时,应该让其他对象来完成某个操作。在表达b1 == a1中,b1.__eq__(a1)返回了NotImplemented,这说明Python试着用a1.__eq__(b1)。由于a1足够可以返回True,因此这个表达可以成功。如果A中的__eq__()也返回NotImplemented,那么运行时会退化到使用内置的比较行为,即比较对象的标识符(在CPython中,是对象在内存中的地址)。

注意:如果在调用b1.__eq__(a1)时抛出NotImpementedError,而不进行处理,就会中断代码的执行。而NotImplemented无法抛出,仅仅是用来进一步测试是否有其他方法可供调用。

 

Guess you like

Origin www.cnblogs.com/jfdwd/p/11294441.html
Recommended