Python for .NET Developers Transcripts
Chapter: The Python Language
Lecture: Python closures
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
We saw this idea of closures in C# was really interesting and powerful. Does Python have something like it? Let's find out.
0:08
Over here, let's create one of these functions that creates this counter, this closure. So, we'll say def create_counter and it takes a start_val
0:18
and a counter_id. So what did we do? Well, we had a print statement, and then what did we do? We defined a delegate type, didn't emphasize that
0:27
we had to create a delegate type and then we defined a delegate instance. Python you have this idea of these delegates as well
0:34
but it's much, much simpler. You just define a function with exactly the same syntax but indented so it's defined here.
0:43
We'll create a counter, which is a void function say has a start, equals a start_val it's going to start from that. Maybe, it's going to increment.
0:54
We called it start before but it's kind of badly named so we said every time you call it we're going to increment
0:58
this by one, and then we're going to print out some kind of formatted string. Like this, we're going to say the current counter_id is this
1:07
and we started at this and now our current value is whatever we've incremented it to. Notice though, there's something a little bit
1:13
funny going on here. We have these values that seem to be captured just fine but this increment, there's something off with it
1:21
it says we don't know what that is. And in order to tell this function it's allowed to capture local variables or even just to try to print it out
1:29
you have to use a new keyword, a nonlocal inc and that says I'd like you to reach up to this intermediate scope, it's not global
1:38
it's not defined here, and work with it. Sometimes you have to use nonlocal, sometimes you don't it's not entirely obvious when that is true
1:46
but down here we can return count, counter not like this, that would call it, just the name. So we're turning this function that was defined right here
1:56
and it's actually going to do closure on these values just like before. So let's go over here and say counter1 = create_counter, start value
2:05
and we have 7 and the id was 1. So let's just call counter a few times like that we run this, and we run the right thing. Look at that.
2:17
Counter with id 111 it's start value is 7 now it's 8, now it's 9, now it's 10. Pretty cool, right? So exactly like C#, except for we didn't have
2:28
to jump through hoops to specify the return type here of whatever this delegate type that we're going to define we just said no, here's a function
2:36
really more generally, there's something. Here's a thing that can be called 'cause classes and other objects can implement
2:41
something along those lines as well and then we just passed it back. We also just had another one that was at -100
2:47
and this was id 2, that we said counter2, counter2 and then we did that three times. Run it one more time, okay. Counter id 1, 1 and 1
2:58
still goes from 7 to 8, seven to 9, 7 to 10. And number 2 is going from -100 to -99 to -98, to -97, exactly like the C# closure
3:09
that we had before. Cool, right? So, same thing if you have lambda expressions or those little types of things
3:15
you can use closure to capture those values into interesting things. But just be careful because these values are remembered
3:22
they don't reset like normal functions.