Overriding the 'not' operator in Python

Question:

I cannot find the method corresponding to not x operator. There is one for and, or, and xor, though. Where is it?

3. Data model

Asked By: ArekBulski

||

Answers:

There is one for and, or, and xor, though

The methods you’re looking at are for bitwise &, |, and ^, not and, or, or xor (which isn’t even a Python operator).

not cannot be overloaded, just like and and or can’t be overloaded. Bitwise ~ can be overloaded, though; that’s __invert__.

If you’re in a situation where you wish you could overload not, you’ll either have to make do with overloading ~ instead, or you’ll have to write your own logical_not function and use that instead of the not operator.

Answered By: user2357112

There are no hooks for and or or operators, no (as they short-circuit), and there is no xor operator in Python. The __and__ and __or__ are for the bitwise & and | operators, respectively. The equivalent bitwise operator for not is ~ (inversion), which is handled by the __invert__ method, while __xor__ covers the ^ bitwise operator.

not operates on the truth-value of an object. If you have a container, give it a __len__ method, if not give it a __bool__ method. Either one is consulted to determine if an object should be considered ‘true’; not inverts the result of that test.

So if __bool__ returns True or __len__ returns an integer other than 0, not will invert that to False, otherwise not produces True. Note that you can’t make not return anything else but a boolean value!

From the documentation for __bool__:

__bool__
Called to implement truth value testing and the built-in operation bool(); should return False or True. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.>

and for the not expression:

In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: False, None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. User-defined objects can customize their truth value by providing a __bool__() method.

The operator not yields True if its argument is false, False otherwise.

bold emphasis mine.

Answered By: Martijn Pieters