|
1 | 1 | # 闭包 |
2 | 2 |
|
3 | | -## 1.函数定义 |
| 3 | +## 一.函数定义 |
4 | 4 |
|
5 | 5 | demo: |
6 | 6 |
|
@@ -45,148 +45,120 @@ test is show |
45 | 45 |
|
46 | 46 | 第二行的时候,python执行了,创建一个对象引用名称为test并指向第三行的内存地址,data指向数据123的内存地址 |
47 | 47 |
|
48 | | -**为什么要类,函数?** |
| 48 | +> 为什么要类|函数? |
| 49 | +> |
| 50 | +> 功能:一个函数做一件事(功能) |
| 51 | +> 类:方便相关函数管理 |
49 | 52 |
|
50 | | - 一个函数做一件事(功能) |
51 | | - 类:方便相关函数管理 |
| 53 | +## 二. 什么是闭包 |
52 | 54 |
|
| 55 | +**定义:** |
53 | 56 |
|
| 57 | +指在一个函数内部定义的函数,内部函数可以访问并操作外部函数的变量,即使外部函数已经执行结束。闭包在Python中通常用于保留局部状态、创建函数工厂和实现回调,它是基于函数嵌套和作用域的特性。 |
54 | 58 |
|
55 | | -## 2. 什么是闭包 |
56 | | - |
57 | | -定义: |
| 59 | +**结构:** |
58 | 60 |
|
59 | 61 | 两个函数嵌套,外部函数返回内部函数的引用,并且外部函数都有参数 |
60 | 62 |
|
61 | | -结构: |
62 | | - |
63 | 63 | ``` |
64 | 64 | def 外部函数(args): |
65 | 65 | def 内部函数(): |
66 | 66 | pass |
67 | 67 | return 内部函数引用 |
68 | 68 | ``` |
69 | 69 |
|
70 | | -demo: |
| 70 | +**闭包示例:** |
71 | 71 |
|
72 | 72 | ```python |
73 | | -# 定义一个函数 |
74 | | -def test(number): |
75 | | - |
76 | | - # 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包 |
77 | | - def test_in(number_in): |
78 | | - print("in test_in 函数, number_in is %d" % number_in) |
79 | | - return number+number_in |
80 | | - # 其实这里返回的就是闭包的结果 |
81 | | - return test_in |
82 | | - |
| 73 | +def outer_function(x): |
| 74 | + def inner_function(y): |
| 75 | + return x + y |
| 76 | + return inner_function |
| 77 | + |
| 78 | +closure = outer_function(5) |
| 79 | +result = closure(3) # 这里调用闭包 |
| 80 | +print(result) # 输出结果为 8 |
| 81 | +``` |
83 | 82 |
|
84 | | -# 给test函数赋值,这个20就是给参数number |
85 | | -ret = test(20) |
| 83 | +在这个例子中,`outer_function` 返回了 `inner_function`,`inner_function` 中引用了 `outer_function` 中的变量 `x`。 |
86 | 84 |
|
87 | | -# 注意这里的100其实给参数number_in |
88 | | -print(ret(100)) |
| 85 | +即使 `outer_function` 已经执行完并返回了 `inner_function`,`inner_function` 仍然保留了对 `x` 的引用。 |
89 | 86 |
|
90 | | -#注 意这里的200其实给参数number_in |
91 | | -print(ret(200)) |
92 | | -``` |
| 87 | +当你调用 `closure(3)` 时,实际上执行的是 `5 + 3` 的操作,所以结果为 8。 |
93 | 88 |
|
| 89 | +> 注意: |
| 90 | +> |
| 91 | +> 闭包在需要在函数调用之间保持某些状态,并且需要使用函数内的变量时非常有用。它可以用于保持局部状态、实现回调函数、函数工厂,以及一些函数式编程的概念。 |
94 | 92 |
|
| 93 | +**实例操作:** |
95 | 94 |
|
96 | | -案例:把中国的钱转换成外国的钱,汇率的值*钱 = 新钱 |
| 95 | +把中国的钱转换成外国的钱,汇率的值*钱 = 新钱 |
97 | 96 |
|
98 | 97 | demo: |
99 | 98 |
|
100 | 99 | ```python |
101 | | -# -*- coding:utf-8 -*- |
102 | | -# 第一种方法 |
103 | | -# 每次都更具汇率和钱都写一遍 |
104 | | -# 这种方法是太烦了 |
105 | | -print("第一种方法") |
106 | | -rate_usa = 0.7 |
107 | | -money = 100 |
108 | | -# print(rate_usa * money) |
109 | | -print("第一种方法结束") |
110 | | - |
111 | | -# 第二种方法封装成函数 |
112 | | -# 这种方法还是太烦 |
113 | | -print("第二种方法") |
| 100 | +# 方法一 |
| 101 | +rate = 0.7 # 汇率 |
| 102 | +money = 100 # 要转换的金额 |
| 103 | +result = rate * money |
| 104 | +print(result) |
114 | 105 |
|
115 | 106 |
|
| 107 | +# 方法二 |
116 | 108 | def count_rate(rate, money): |
117 | | - print(rate * money) |
118 | | - |
| 109 | + return rate * money |
119 | 110 |
|
120 | | -count_rate(100, 1000) |
121 | | -print("第二种方法结束") |
122 | 111 |
|
123 | | -# 第三种方法用缺省参数来代替汇率的输入 |
124 | | -# 这种方法还是太烦 |
125 | | -print("第三种方法") |
| 112 | +print(count_rate(0.7, 100)) |
126 | 113 |
|
127 | 114 |
|
| 115 | +# 方法三 |
128 | 116 | def count_rate(money, rate=0.7): |
129 | | - print(money * rate) |
| 117 | + return rate * money |
130 | 118 |
|
131 | 119 |
|
132 | | -count_rate(100) |
133 | | -count_rate(100, 1000) |
134 | | -print("第三种方法结束") |
| 120 | +print(count_rate(100)) |
| 121 | +print(count_rate(100, 0.8)) |
135 | 122 |
|
136 | | -# 第四种方法用全局变量来代替汇率的输入 |
137 | | -# 这种方法还是太烦 |
138 | | -print("第四种方法") |
139 | | -rate = 100 |
| 123 | +# 方法四 |
| 124 | +rate = 0.7 # 全局变量 |
140 | 125 |
|
141 | 126 |
|
142 | 127 | def count_rate(money): |
143 | | - print(money * rate) |
| 128 | + return rate * money |
144 | 129 |
|
145 | 130 |
|
146 | | -count_rate(100) |
147 | | -print("第四种方法结束") |
148 | | - |
149 | | -# 第五种方法分装成类 |
150 | | -# 这种方法魔法方法 太多还是太烦 |
151 | | -print("第五种方法") |
| 131 | +print(count_rate(100)) |
152 | 132 |
|
153 | 133 |
|
| 134 | +# 方法五 |
154 | 135 | class CountRate(object): |
155 | 136 | def __init__(self, rate): |
156 | 137 | self.rate = rate |
157 | 138 |
|
158 | 139 | def __call__(self, money): |
159 | | - print(self.rate * money) |
160 | | - |
| 140 | + return self.rate * money |
161 | 141 |
|
162 | | -usa = CountRate(0.7) |
163 | | -usa(200) |
164 | | -rate_jp = CountRate(1000) |
165 | | -rate_jp(1000) |
166 | 142 |
|
167 | | -print("第五种方法结束") |
| 143 | +obj = CountRate(0.7) |
| 144 | +obj(100) |
168 | 145 |
|
169 | | -# 第六种方法:闭包解决 |
170 | | -print("第六种方法") |
171 | 146 |
|
| 147 | +# 方法六 |
| 148 | +def func(rate): |
| 149 | + def func_in(money): |
| 150 | + return rate * money |
172 | 151 |
|
173 | | -def count(rate): |
174 | | - def money(money): |
175 | | - print(rate * money) |
| 152 | + return func_in |
176 | 153 |
|
177 | | - return money |
178 | 154 |
|
179 | | - |
180 | | -usa_rate = count(0.7) |
181 | | -usa_rate(100) |
182 | | -print("第六种方法结束") |
| 155 | +count_rate = func(0.7) |
| 156 | +print(count_rate(100)) |
183 | 157 | ``` |
184 | 158 |
|
185 | | - |
186 | | - |
187 | | -**注意点:** |
188 | | - |
189 | | -由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存 |
| 159 | +> 注意点: |
| 160 | +> |
| 161 | +> 由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存 |
190 | 162 |
|
191 | 163 |
|
192 | 164 |
|
|
0 commit comments