Closures in Python

def incorrect():
    fruit = ['apples', 'bananas', 'peaches']
    printers = {}

    for food in fruit:
        def output():
          print food
        printers[food] = output

    printers['apples']()
    printers['bananas']()
    printers['peaches']()

def correct():
    fruit = ['apples', 'bananas', 'peaches']
    printers = {}

    for food in fruit:
        def create_output(food):
            def output():
                print food
            return output
        printers[food] = create_output(food)

    printers['apples']()
    printers['bananas']()
    printers['peaches']()
>>> incorrect()
peaches
peaches
peaches
>>> correct()
apples
bananas
peaches

3 Comments

  1. Posted February 8, 2008 at 5:43 pm | Permalink

    The correct method implements a closure.

  2. Jayce
    Posted February 8, 2008 at 11:05 pm | Permalink

    Used to the scoping rules of C, C++, and Java, I used to think that constructs like for/while/try-catch-finally blocks had their own scope and soon found they didn’t. It was only after reading how all Python scopes are associated with Python objects that the light-bulb went on! :-)

    Modules, functions, classes, objects, packages, etc. are all objects, and each object has its scope (a dictionary).

    This is kind of a neat idea. However, it could trip up those who are used to the block=scope rule from C/C++/Java/Perl.

  3. Posted April 11, 2008 at 12:09 am | Permalink

    You are the brick! Reading stuff like this written in the way like this is a great pleasure for me.

Post a Comment

Your email is never published nor shared.