-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclousureT.py
More file actions
155 lines (98 loc) · 3.24 KB
/
Copy pathclousureT.py
File metadata and controls
155 lines (98 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# ==========================================================
# CLOSURES IN PYTHON
# ==========================================================
# A closure is a function object that remembers values
# from its enclosing (outer) function even after the outer
# function has finished execution
# ==========================================================
# 1. NESTED FUNCTIONS
# ==========================================================
def outer():
print("Outer function")
def inner():
print("Inner function")
inner()
outer()
# ==========================================================
# 2. ACCESSING ENCLOSING SCOPE
# ==========================================================
def outer():
x = 10 # enclosing variable
def inner():
print("Accessing outer variable:", x)
inner()
outer()
# ==========================================================
# 3. CREATING A CLOSURE
# ==========================================================
def outer():
x = 100 # variable to be captured
def inner():
print("Captured value:", x)
return inner # return inner function (closure)
closure_func = outer() # outer() finishes execution
closure_func() # still remembers x = 100
# ==========================================================
# 4. RETENTION OF STATE
# ==========================================================
def counter():
count = 0
def increment():
# count += 1 # ERROR without nonlocal
print("Count:", count)
return increment
c = counter()
c() # always prints 0 (no modification)
# ==========================================================
# 5. nonlocal KEYWORD
# ==========================================================
# used to modify variable from enclosing scope
def counter():
count = 0
def increment():
nonlocal count # refers to outer variable
count += 1
print("Count:", count)
return increment
c = counter()
c() # 1
c() # 2
c() # 3
# ==========================================================
# 6. MULTIPLE CLOSURES WITH DIFFERENT STATES
# ==========================================================
def make_multiplier(n):
def multiply(x):
return x * n # n is captured
return multiply
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
# ==========================================================
# 7. CHECKING CLOSURE VARIABLES
# ==========================================================
def outer():
x = 50
def inner():
return x
return inner
f = outer()
print(f.__closure__) # shows closure cells
print(f.__closure__[0].cell_contents) # value of x
# ==========================================================
# SUMMARY (IN COMMENTS)
# ==========================================================
# Nested Function:
# function inside another function
# Closure:
# inner function that remembers outer variables
# Key Features:
# - access enclosing scope
# - retain state after outer function ends
# nonlocal:
# - used to modify outer (non-global) variable
# - required for state changes inside closure
# Use Cases:
# - function factories
# - maintaining state without global variables