[Python-Dev] the not operator (and the __not__ special method)

Guido van Rossum guido@python.org
Thu, 03 Oct 2002 17:40:27 -0400


> The following test code:
> 
> 
> class Hello:
>     def __not__(self):
>         return "calling Hello.__not__"

The reference manual (chapter 3) does not define __not__ as a special
operator.

>     def __neg__(self):
>         return "calling Hello.__neg__"
> 
> a = Hello()
> print -a
> print not a
> 
> 
> shows that python doesn't call the __not__ special method
> in a 'not' operator statement.
> 
> The Modules/operator.c file, line 234, says:
> 
> spam2(neg,__neg__, "neg(a) -- Same as -a.")
> spam2(pos,__pos__, "pos(a) -- Same as +a.")
> spam2(abs,__abs__, "abs(a) -- Same as abs(a).")
> spam2(inv,__inv__, "inv(a) -- Same as ~a.")
> spam2(invert,__invert__, "invert(a) -- Same as ~a.")
> spam2(lshift,__lshift__, "lshift(a, b) -- Same as a << b.")
> spam2(rshift,__rshift__, "rshift(a, b) -- Same as a >> b.")
> spam2(not_,__not__, "not_(a) -- Same as not a.")

The operator module uses __not__ as a function name for symmetry with
its other function names, not because __not__ is a special operator.

> so, one can expect that like "-a" is equivalent ot "a.__neg__()",
> then  "not a" is equivalent to "a.__not__()",  right?

No.

> Another question, I notice than  "a or b" and "a and b" are
> not equivalent to "a | b" and "a & b", since the last ones call
> the methods __or__ and __and__ if they are defined, but
> the "literal forms" never call them.  Is this intentional?, if
> that is the case, I guess a big and clear note is needed
> in the documentation.

That all depends.  The non-equivalency between 'or' and '|' (and
between 'and' and '&') is quite well documented.  'or' and 'and'
cannot invoke an operator, because the right operand is not evaluated
at all when the left argument determines the outcome.

> Maybe the reason that the literal forms (and,or) are not equivalent to
> the operator forms(&,|)  is preventing python to porperly
> resolve the "not" operation.

No.

> And just for symmetry considerations, given that python has the
> pairs (and, &) and (or, |), does anybody considering to introduce
> the ! operator, so you can have the equivalent (not, !) too?

No, there's no shortcut possibility for not as there is for 'and' and
'or'.

--Guido van Rossum (home page: http://www.python.org/~guido/)