I learn something new every day.
First, the sort of thing you could do to mess with someone when they step away from their Python interactive shell to go use the restroom:
>>> False = True >>> False True >>> if False: print "Woo!" ... Woo!
Sure enough, True and False are just names in the builtin namespace that can be rebound. This capability seems pretty dangerous, so I'd expect to see something like it in C or in Lisp, but its presence in Python surprised me a bit.
Second, the following puzzle stumped me for a while when I first saw it. Why does the following expression evaluate as it does?
>>> "string" in  == False False
It's not a precedence issue, because that result is not consistent with either of the parenthesizations:
>>> ("string" in ) == False True >>> "string" in ( == False) Traceback (most recent call last): File "
", line 1, in TypeError: argument of type 'bool' is not iterable
It's actually a consequence of Python's support for chained comparison operators. That is, just as
5 < a <= 7
5 < a and a <= 7,
the first expression above desugars to "string" in  and  == False, which is False.
It's good that the comparison operators (< <= > >= == != in is) work in this consistent way, but it can trip up Python novices who have not yet learned that they really have to write the more Pythonic expression "string" not in  if they want to stay out of trouble.