Python Gotchas

Posted by lorne on September 4th, 2006 — Posted in General

I’m currently required to use Python for COMP312. Having come from doing nothing but Haskell and Prolog in COMP304 you can imagine my mind isn’t exactly bent around Python’s way of doing things. Here are a couple of traps I ran into

First off is expressions and lambda

>>> def p(x): print(x)
...
>>> f = lambda x:p(x)
>>> f(5)
5
>>> f = lambda x:print(x)
  File "<stdin>", line 1
    f = lambda x:print(x)
                     ^
SyntaxError: invalid syntax

You cannot put an expression in a lambda. What’s more there is no implicit return value in Python. There was a thread about this, for those of you with access to the MSCS forums. After that last post I wasn’t sure how to reply

Next up is scope

>>> def counter(x):
...     base = x
...     def inc():
...             oldbase = base
...             base = base + 1
...             return oldbase
...     return inc
...
>>> c = counter(5)
>>> c()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 4, in inc
UnboundLocalError: local variable 'base' referenced before assignment

“Oh, but that should happen as base shouldn’t leak into inc!”

>>> def counter(x):
...     base = x
...     def inc():
...             oldbase = base
...             return base
...     return inc
...
>>> c = counter(5)
>>> c()
5

Python is happy to read variables and mutate objects, but introducing assignment makes Python come up with a new variable for you. The obvious argument is that this counter should be a class. Perhaps true, but it still caught me out.

3 Comments »

Comment by qwandor

There is a typo in your links to the COMP312 and COMP304 pages.

Posted on September 4, 2006 at 9:20 pm

Comment by lorne

Fixed, thank you.

Posted on September 4, 2006 at 9:23 pm

Comment by anon

1/ “print” is not an expression in python, but an instruction (you can write “print 42″ (or even “print >> sys.stderr, 42″), whom syntax clearly shows it’s not an expression), so can’t be included where an expression is expected => not a gotcha (in python 3000, “print” becomes a function (thus an expression too), and the “print 42″ syntax is not valid then)
2/ python, like scheme or many well-designed languages, has lexical scoping, so “base” leaks in “inc” for reading, but python doesn’t like mixing scopes for a same name ; you read the more external scope OR you write it in local scope, and then it refers only to local scope => semi-gotcha

Posted on August 11, 2008 at 11:05 pm

RSS feed for comments on this post. TrackBack URI

Leave a comment