This article describes how to use the built-in NotImplemented type in Python, including the usage of the related _ eq _ () and _ ne _ () methods, for more information, see
What is it?
>>> type(NotImplemented)
NotImplemented is one of the six constants of Python in the built-in namespace. Others include False, True, None, Ellipsis, and _ debug __. Like Ellipsis, NotImplemented can be re-assigned (overwritten ). Assign a value to it, or even change the attribute name, without a SyntaxError. So it is not a real "true" constant. Of course, we should never change it. But for Integrity:
>>> None = 'hello'...SyntaxError: can't assign to keyword>>> NotImplementedNotImplemented>>> NotImplemented = 'do not'>>> NotImplemented'do not'
What is its use? When will it be used?
NotImplemented is a special value that can be returned by binary special methods (such as _ eq _ (), _ lt _ (), and _ add __(), _ rsub _ () indicates that a type does not implement these operations as other types do. Similarly, it may be returned by binary special methods of in place (such as _ imul _ () and _ iand ). Also, its actual value is True:
>>> bool(NotImplemented)True
You may ask yourself, "but I think that when this operation is not implemented, I should generate NotImpementedError ". We will look at some examples to see why this is not the case when implementing binary special methods.
Let's take A look at the usage of NotImplemented constants and encode two very basic (and useless) classes A and B through _ eq. [For this simple example, _ ne _ () is not implemented to avoid interference, but in general, every time _ eq _ () is implemented, _ ne _ () should also be implemented unless there is a sufficient reason not to implement it.]
# 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:
>>> from example import A, B>>> a1 = A(1)>>> b1 = B(1)
Now we can experiment with different calls for _ eq _ () to see what happened. As a reminder, in Python, a = B will call a. _ eq _ (B ):
>>> a1 == a1Comparing an A with an ATrue
As expected, a1 is equal to a1 (itself) and uses _ eq _ () in Class A for this comparison. Comparing b1 and itself produces similar results:
>>> b1 == b1Comparing a B with another BTrue
Now, what if we compare a1 and b1? Because the _ eq _ () of A checks whether other is an instance of B, we want a1. _ eq _ (b1) to process the comparison and return True:
>>> a1 == b1Comparing an A with a BTrue
That's it. Now, if we compare b1 and a1 (call b1. _ eq _ (a1), we will want to return NotImplemented. This is because B's _ eq _ () is only compared with other B's instances. To see what happened:
>>> b1 == a1Could not compare B against the other classComparing an A with a BTrue
Smart! The b1. _ eq _ (a1) method returns NotImplemented, which will call the _ eq _ () method in. In addition, because _ eq _ () in A defines the comparison between A and B, the correct result (True) is obtained ).
This is what NotImplemented does. NotImplemented tells the runtime to allow other objects to complete an operation. In expression b1 = a1, b1. _ eq _ (a1) returns NotImplemented, which means Python tries to use a1. _ eq _ (b1 ). Because a1 is sufficient to return True, this expression can be successful. If _ eq _ () in A also returns NotImplemented, the runtime degrades to using the built-in comparison behavior, that is, the identifier of the comparison object (in CPython, is the address of the object in the memory ).
Note: If NotImpementedError is thrown when b1. _ eq _ (a1) is called without processing, code execution will be interrupted. NotImplemented cannot be thrown. it is only used to further test whether other methods are available for calling.