2

Python documentation for shifting operations and binary bitwise operations says that arguments must be integers, but the below expressions evaluates without error, however giving odd results for << and >>.

Is there an additional place I should look for documentation of & etc. when using boolean arguments, or is there some good explanation for evaluation and results ?

  • True & False: False (class 'bool')
  • True | False: True (class 'bool')
  • True ^ False: True (class 'bool')
  • ~ True: -2 (class 'int')
  • ~ False: -1 (class 'int')
  • True << True: 2 (class 'int')
  • False >> False: 0 (class 'int')

Code:

# Python ver. 3.3.2

def tryout(s):
    print(s + ':', eval(s), type(eval(s)))

tryout('True & False')
tryout('True | False')
tryout('True ^ False')
tryout('~ True')
tryout('~ False')
tryout('True << True')
tryout('False >> False')
Morten Zilmer
  • 15,586
  • 3
  • 30
  • 49

1 Answers1

5

bool is a subclass of int, hence they are integers. In particolar True behaves like 1 and False behaves like 0.

Note that bool only reimplements &, | and ^(source: source code at Objects/boolobject.c in the python sources), for all the other operations the methods of int are used[actually: inherited], hence the results are ints and the semantics are those of the integers.

Regarding << and >>, the expression True << True is equivalent to 1 << 1 i.e. 1 * 2 == 2, while False >> False is 0 >> 0, i.e. 0 * 1 == 0.

You should think python's True and False as 1 and 0 when doing arithmetic operations on them. The reimplementation of &, | and ^ only affect the return type, not the semantics.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • One probably shouldn't do arithmetic on `bool` values at all. Treat the fact that `bool` is a subclass of `int` as an implementation detail, not a semantic assertion that a `bool` is-a `int`. See http://stackoverflow.com/q/8169001/1126841. – chepner Aug 22 '13 at 13:14
  • @chepner Sometimes it *may* be acceptable to do things such as `sum(element in set for element in iterable)` instead of the longer `sum(1 for element in iterable if element in set)`. – Bakuriu Aug 22 '13 at 13:34
  • The reason for looking into this at all, is that the augmented assignment statements `&=`, `^=`, and `|=` may be useful for `bool` arguments also, and since I understand that `&`, `^`, and `|` are reimplemented for `bool`, I assume that the augmented assign statements are OK to use for these operators. – Morten Zilmer Aug 22 '13 at 13:41
  • 1
    @MortenZdk Yes. In fact numbers do *not* implement in-place assignments at all. Python behaviour when executing compound assignment is to see whether it is implemented, and if it isn't then it calls the normal operator and rebinds the object, hence there is no need for `int`, `bool`, `float`, `tuple` (or any immutable type) to implement the in-place assignments methods. You can test this implementing only the `__add__` method in a class and seeing that doing `+=` will call it if no `__iadd__` method is found. – Bakuriu Aug 22 '13 at 16:54