Skip to content

Commit 988241a

Browse files
author
wangtao
committed
完成装饰器章节
1 parent c9139b8 commit 988241a

17 files changed

Lines changed: 449 additions & 121 deletions

‎docs/50.闭包.md‎

Lines changed: 57 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 闭包
22

3-
## 1.函数定义
3+
## 一.函数定义
44

55
demo:
66

@@ -45,148 +45,120 @@ test is show
4545

4646
第二行的时候,python执行了,创建一个对象引用名称为test并指向第三行的内存地址,data指向数据123的内存地址
4747

48-
**为什么要类,函数?**
48+
> 为什么要类|函数?
49+
>
50+
> 功能:一个函数做一件事(功能)
51+
> 类:方便相关函数管理
4952
50-
一个函数做一件事(功能)
51-
类:方便相关函数管理
53+
## 二. 什么是闭包
5254

55+
**定义:**
5356

57+
指在一个函数内部定义的函数,内部函数可以访问并操作外部函数的变量,即使外部函数已经执行结束。闭包在Python中通常用于保留局部状态、创建函数工厂和实现回调,它是基于函数嵌套和作用域的特性。
5458

55-
## 2. 什么是闭包
56-
57-
定义:
59+
**结构:**
5860

5961
两个函数嵌套,外部函数返回内部函数的引用,并且外部函数都有参数
6062

61-
结构:
62-
6363
```
6464
def 外部函数(args):
6565
def 内部函数():
6666
pass
6767
return 内部函数引用
6868
```
6969

70-
demo:
70+
**闭包示例:**
7171

7272
```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+
```
8382

84-
# 给test函数赋值,这个20就是给参数number
85-
ret = test(20)
83+
在这个例子中,`outer_function` 返回了 `inner_function`,`inner_function` 中引用了 `outer_function` 中的变量 `x`。
8684

87-
# 注意这里的100其实给参数number_in
88-
print(ret(100))
85+
即使 `outer_function` 已经执行完并返回了 `inner_function`,`inner_function` 仍然保留了对 `x` 的引用。
8986

90-
#注 意这里的200其实给参数number_in
91-
print(ret(200))
92-
```
87+
当你调用 `closure(3)` 时,实际上执行的是 `5 + 3` 的操作,所以结果为 8。
9388

89+
> 注意:
90+
>
91+
> 闭包在需要在函数调用之间保持某些状态,并且需要使用函数内的变量时非常有用。它可以用于保持局部状态、实现回调函数、函数工厂,以及一些函数式编程的概念。
9492
93+
**实例操作:**
9594

96-
案例:把中国的钱转换成外国的钱,汇率的值*钱 = 新钱
95+
把中国的钱转换成外国的钱,汇率的值*钱 = 新钱
9796

9897
demo:
9998

10099
```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)
114105

115106

107+
# 方法二
116108
def count_rate(rate, money):
117-
print(rate * money)
118-
109+
return rate * money
119110

120-
count_rate(100, 1000)
121-
print("第二种方法结束")
122111

123-
# 第三种方法用缺省参数来代替汇率的输入
124-
# 这种方法还是太烦
125-
print("第三种方法")
112+
print(count_rate(0.7, 100))
126113

127114

115+
# 方法三
128116
def count_rate(money, rate=0.7):
129-
print(money * rate)
117+
return rate * money
130118

131119

132-
count_rate(100)
133-
count_rate(100, 1000)
134-
print("第三种方法结束")
120+
print(count_rate(100))
121+
print(count_rate(100, 0.8))
135122

136-
# 第四种方法用全局变量来代替汇率的输入
137-
# 这种方法还是太烦
138-
print("第四种方法")
139-
rate = 100
123+
# 方法四
124+
rate = 0.7 # 全局变量
140125

141126

142127
def count_rate(money):
143-
print(money * rate)
128+
return rate * money
144129

145130

146-
count_rate(100)
147-
print("第四种方法结束")
148-
149-
# 第五种方法分装成类
150-
# 这种方法魔法方法 太多还是太烦
151-
print("第五种方法")
131+
print(count_rate(100))
152132

153133

134+
# 方法五
154135
class CountRate(object):
155136
def __init__(self, rate):
156137
self.rate = rate
157138

158139
def __call__(self, money):
159-
print(self.rate * money)
160-
140+
return self.rate * money
161141

162-
usa = CountRate(0.7)
163-
usa(200)
164-
rate_jp = CountRate(1000)
165-
rate_jp(1000)
166142

167-
print("第五种方法结束")
143+
obj = CountRate(0.7)
144+
obj(100)
168145

169-
# 第六种方法:闭包解决
170-
print("第六种方法")
171146

147+
# 方法六
148+
def func(rate):
149+
def func_in(money):
150+
return rate * money
172151

173-
def count(rate):
174-
def money(money):
175-
print(rate * money)
152+
return func_in
176153

177-
return money
178154

179-
180-
usa_rate = count(0.7)
181-
usa_rate(100)
182-
print("第六种方法结束")
155+
count_rate = func(0.7)
156+
print(count_rate(100))
183157
```
184158

185-
186-
187-
**注意点:**
188-
189-
由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
159+
> 注意点:
160+
>
161+
> 由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
190162
191163

192164

‎docs/51.装饰器.md‎

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
# 装饰器
22

3-
## 1.什么是装饰器?
3+
## 一.装饰器示意和原理
44

5-
装饰器是在不改变原有代码的情况下为代码添加新的功能
5+
允许向已存在的函数或类添加额外的功能,而不修改它们的结构。装饰器本质上是一个可调用的函数,用于修改其他函数或类的行为。
6+
7+
### 1.结构
8+
9+
```
10+
def 外部函数(函数名):
11+
def 内部函数(参数):
12+
return 函数()
13+
return 内部函数引用
14+
15+
@外部函数名 # 语法糖
16+
def 函数名():
17+
pass
18+
```
19+
20+
### 2.作用
21+
22+
**在函数执行前后执行特定操作:** 比如日志记录、性能监控等。
23+
24+
**修改函数的行为:** 对函数的返回值或参数进行操作或验证。
25+
26+
**缓存或注册函数:** 对函数进行缓存,以避免重复计算,或者将函数注册到某个列表或字典中进行管理。
27+
28+
### 3.原理
629

730
**看下面这段代码:**
831

@@ -103,24 +126,9 @@ test()
103126
test is show
104127
```
105128

106-
**结构:**
107-
108-
```
109-
def 外部函数(函数名):
110-
def 内部函数(参数):
111-
return 函数()
112-
return 内部函数引用
113-
114-
@外部函数名 # 语法糖
115-
def 函数名():
116-
pass
117-
```
118-
129+
## 二.装饰器种类
119130

120-
121-
## 2.装饰器种类
122-
123-
### <1>.对于无参数无返回值的函数的装饰器
131+
### 1.无参无返的装饰器
124132

125133
demo:
126134

@@ -142,7 +150,7 @@ def test():
142150
test()
143151
```
144152

145-
### <2>.对于有参数无返回值的函数的装饰器
153+
### 2.有参无返的装饰器
146154

147155
demo:
148156

@@ -169,7 +177,7 @@ test(100)
169177
test is show100
170178
```
171179

172-
### <3>.对于无参数无返回值的函数的装饰器
180+
### 3.无参有返的装饰器
173181

174182
demo:
175183

@@ -195,7 +203,7 @@ print(test())
195203
test is show
196204
```
197205

198-
### <4>.对于无参数无返回值的函数的装饰器
206+
### 4.有参有返的装饰器
199207

200208
demo:
201209

@@ -222,7 +230,7 @@ print(test(100))
222230
test is show100
223231
```
224232

225-
### <5>.通用装饰器
233+
### 5.通用装饰器
226234

227235
demo:
228236

@@ -243,9 +251,7 @@ def test(data):
243251
print(test(100))
244252
```
245253

246-
247-
248-
## 3.通用装饰器可以装饰任何函数
254+
## 三.通用装饰器可以装饰任何函数
249255

250256
```
251257
def 外部函数名(函数引用):
@@ -257,9 +263,7 @@ def 函数名():
257263
pass
258264
```
259265

260-
261-
262-
## 4.多个装饰器装饰一个函数
266+
## 四.多个装饰器装饰一个函数
263267

264268
demo:
265269

@@ -306,15 +310,13 @@ call_fun1执行了
306310
test is show
307311
```
308312

309-
**总结:**
310-
311-
多个装饰器装饰同一个函数的的运行顺序为,先把多装饰外部由下向上得到引用再由上向下执行内部引用
312-
313+
> 总结
314+
>
315+
> 多个装饰器装饰同一个函数的的运行顺序为,先把多装饰外部由下向上得到引用再由上向下执行内部引用
313316
317+
## 五.类装饰器
314318

315-
## 5.类装饰器
316-
317-
结构:
319+
**结构:**
318320

319321
```
320322
class 类名(object):
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#! /usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# @Time : 2023/10/30 17:06
4+
# @Author : toby
5+
# @File : 1.函数定义.py
6+
# @Software: PyCharm
7+
# @Desc:
8+
9+
def func(data):
10+
print(f"test is show data:{data}")
11+
12+
13+
# 调用函数
14+
func(111)
15+
16+
# 引用函数
17+
ret = func
18+
19+
print(ret)
20+
print(func)
21+
22+
# 通过引用调用函数
23+
ret(222)
24+
25+
26+
# 把函数单成参数传递
27+
def functions(func):
28+
func(333)
29+
30+
31+
functions(ret)

0 commit comments

Comments
 (0)