Read/Write Python Closures Read/Write Python Closures python python

Read/Write Python Closures


To expand on Ignacio's answer:

def counter():    count = 0    def c():        nonlocal count        count += 1        return count    return cx = counter()print([x(),x(),x()])

gives [1,2,3] in Python 3; invocations of counter() give independent counters. Other solutions - especially using itertools/yield are more idiomatic.


You could do this and it would work more or less the same way:

class counter(object):    def __init__(self, count=0):        self.count = count    def __call__(self):        self.count += 1        return self.count    

Or, a bit of a hack:

def counter():    count = [0]    def incr(n):        n[0] += 1        return n[0]    return lambda: incr(count)

I'd go with the first solution.

EDIT: That's what I get for not reading the big blog of text.

Anyway, the reason Python closures are rather limited is "because Guido felt like it." Python was designed in the early 90s, in the heyday of OO. Closures were rather low on the list of language features people wanted. As functional ideas like first class functions, closures, and other things make their way into mainstream popularity, languages like Python have had to tack them on, so their use may a bit awkward, because that's not what the language was designed for.

<rant on="Python scoping">

Also, Python (2.x) has rather odd (in my opinion) ideas about scoping that interferes with a sane implementation of closures, among other things. It always bothers me that this:

new = [x for x in old]

Leaves us with the name x defined in the scope we used it in, as it is (in my opinion) a conceptually smaller scope. (Though Python gets points for consistency, as doing the same thing with a for loop has the same behavior. The only way to avoid this is to use map.)

Anyway, </rant>