Jump to content

  • Log In with Google      Sign In   
  • Create Account


Python closures, me no understand


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 jwezorek   Crossbones+   -  Reputation: 1606

Like
0Likes
Like

Posted 15 February 2012 - 07:58 PM

In the following code:
[source lang="python"]def count_if( func, seq): count = [0] def count_func( x ): if ( func(x) ): count[0] += 1 for x in seq: count_func(x) return count[0][/source]
why do I have to make count a one element list? (obviously I could implement this without a closure I'm just trying to understand how they work.)

Sponsor:

#2 Telastyn   Crossbones+   -  Reputation: 3712

Like
0Likes
Like

Posted 15 February 2012 - 08:04 PM

Are you sure you have to? I know next to nothing about python, but closures in other languages don't make that requirement.

#3 jwezorek   Crossbones+   -  Reputation: 1606

Like
0Likes
Like

Posted 15 February 2012 - 08:10 PM

This
[source lang="python"]def count_if( func, seq): count = 0 def count_func( x ): if ( func(x) ): count += 1 for x in seq: count_func(x) return count[/source]
yields the error "UnboundLocalError: local variable 'count' referenced before assignment." When I google that I see people talking about this sort of thing but I haven't seen a clear explanation.

#4 TheUnbeliever   Members   -  Reputation: 957

Like
0Likes
Like

Posted 15 February 2012 - 08:51 PM

I barely know Python, but this StackOverflow thread seems to describe the problem well enough to me. Basically: if you assign to a variable, that variable is created in the local scope, even if there is an identifier with the same name visible from an enclosing scope. Consequently, if you just read from a captured variable, things are dandy. But if you perform an assignment, even after the read, then it will assume that all references in that (enclosed) scope refer to a closure local. Apparently this is remedied (not very nicely, it has to be said) in Python 3.x.
[TheUnbeliever]

#5 jwezorek   Crossbones+   -  Reputation: 1606

Like
0Likes
Like

Posted 15 February 2012 - 09:08 PM

I barely know Python, but this StackOverflow thread seems to describe the problem well enough to me. Basically: if you assign to a variable, that variable is created in the local scope, even if there is an identifier with the same name visible from an enclosing scope. Consequently, if you just read from a captured variable, things are dandy. But if you perform an assignment, even after the read, then it will assume that all references in that (enclosed) scope refer to a closure local. Apparently this is remedied (not very nicely, it has to be said) in Python 3.x.

But then why does the list version work? ... Oh, I guess I see, because count[0] += 1 does not tell python to create a one element list if count doesn't exist; if count doesn't exist count[0] += 1 is an error. if a list version of count exists *only* in an enclosing scope and you attempt this assignment python assumes you mean that one?

#6 TheUnbeliever   Members   -  Reputation: 957

Like
1Likes
Like

Posted 15 February 2012 - 09:24 PM

You can't assign to 'count' (and have it refer to the same one) but you can modify the list it identifies. So, whilst you can't assign a new list to (the enclosing scope's) 'count', you can increment the first value in the list. You want to distinguish between the location 'count' and the value stored there.
[TheUnbeliever]

#7 jwezorek   Crossbones+   -  Reputation: 1606

Like
0Likes
Like

Posted 15 February 2012 - 09:33 PM

Oh, okay, so if 'count' was any kind of mutable type the enclosed scope can mutate it ... so the enclosed scope basically has access to count's value but doesn't have a reference to count itself.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS