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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
<code>1.</code><code>名称空间</code>
<code>python有三种名称空间</code>
<code>内置名称空间: 随着python解释器的启动而产生</code>
<code>print</code><code>(</code><code>sum</code><code>)</code>
<code>print</code><code>(</code><code>max</code><code>)</code>
<code>全局名称空间: 文件的执行会产生全局名称空间,指的是文件级别的定义名字都会放入该空间</code>
<code>x </code><code>=</code> <code>11</code>
<code>if</code> <code>x </code><code>=</code><code>=</code> <code>11</code><code>:</code>
<code> </code><code>print</code><code>(x)</code>
<code>局部名称空间: 调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束时解绑</code>
<code>x </code><code>=</code> <code>1000</code>
<code>def</code> <code>foo():</code>
<code> </code><code>x </code><code>=</code> <code>1</code>
<code>foo()</code>
<code>print</code><code>(x)</code>
<code>作用域:</code>
<code> </code><code>1.</code><code>全局作用域: 内置名称空间,全局名称空间,全局有效,在任何位置都能被访问到,</code>
<code> </code><code>除非</code><code>del</code><code>删除,否则存活到文件结束。</code>
<code> </code><code>2.</code><code>局部作用域: 局部名称空间,局部有效,只能在局部范围调用,调用结束失效。</code>
<code>名字的查找顺序: 局部名称空间</code><code>-</code><code>-</code><code>>全局名称空间</code><code>-</code><code>-</code><code>>内置名称空间</code>
<code>def</code> <code>func():</code>
<code> </code><code>x </code><code>=</code> <code>2</code>
<code> </code><code>print</code><code>(</code><code>locals</code><code>()) </code><code>#locals()查看局部作用域内的名字</code>
<code>print</code><code>(</code><code>globals</code><code>()) </code><code>#globals()查看全局作用域内的名字</code>
<code>2.</code><code>函数对象</code>
<code> </code><code>1.</code><code>可以被引用</code>
<code> </code><code>2.</code><code>可以当作参数传递</code>
<code> </code><code>3.</code><code>返回值可以是函数</code>
<code> </code><code>4.</code><code>可以当作容器类型的元素</code>
<code> </code>
<code> </code><code>例子:</code>
<code> </code><code>def</code> <code>foo():</code>
<code> </code><code>print</code><code>(</code><code>"from foo"</code><code>)</code>
<code> </code><code>func </code><code>=</code> <code>foo</code>
<code> </code><code>print</code><code>(foo)</code>
<code> </code><code>print</code><code>(func)</code>
<code> </code><code>foo()</code>
<code> </code><code>func()</code>
<code> </code>
<code> </code><code>def</code> <code>bar(func):</code>
<code> </code><code>print</code><code>(func)</code>
<code> </code><code>func()</code>
<code> </code><code>bar(foo)</code>
<code> </code><code>dic </code><code>=</code> <code>{</code><code>'func'</code><code>: foo}</code>
<code> </code><code>print</code><code>(dic[</code><code>'func'</code><code>])</code>
<code> </code><code>dic[</code><code>'func'</code><code>]()</code>
<code>3.</code><code>闭包函数</code>
<code> </code><code>闭包:</code>
<code> </code><code>1.</code><code>定义在内部函数</code>
<code> </code><code>2.</code><code>包含对外部作用域而非全局作用域的引用</code>
<code> </code><code>该内部函数就称作闭包函数</code>
<code> </code><code>例子:</code>
<code> </code><code>def</code> <code>f1():</code>
<code> </code><code>def</code> <code>f2(): </code><code>#f2称作闭包函数</code>
<code> </code><code>print</code><code>(x)</code>
<code> </code><code>return</code> <code>f2</code>
<code> </code><code>f </code><code>=</code> <code>f1()</code>
<code> </code><code>print</code><code>(f) </code><code>#打印f2函数的内存地址</code>
<code> </code><code>f() </code><code>#打印1</code>
<code> </code>
<code> </code><code>例子:</code>
<code> </code><code>from</code> <code>urllib.request </code><code>import</code> <code>urlopen</code>
<code> </code><code>def</code> <code>index(url):</code>
<code> </code><code>def</code> <code>get():</code>
<code> </code><code>return</code> <code>urlopen(url).read()</code>
<code> </code><code>return</code> <code>get</code>
<code> </code><code>oldboy </code><code>=</code> <code>index(</code><code>'http://www.baidu.com'</code><code>)</code>
<code> </code><code>print</code><code>(oldboy().decode(</code><code>'utf-8'</code><code>))</code>
<code> </code><code>print</code><code>(oldboy.__closure__[</code><code>0</code><code>].cell_contents) </code><code>#打印外部引用而非全局引用对象</code>
<code> </code>
<code>4.</code><code>装饰器</code>
<code> </code><code>修饰其他对象的工具,修饰添加功能,工具指的是函数。</code>
<code> </code><code>装饰器本身是任何可调用对象,被装饰的对象也可以是任何可调用的对象。</code>
<code> </code><code>为什么要用装饰器?</code>
<code> </code><code>开放封闭原则,对修改是封闭的,对扩展是开放的。</code>
<code> </code><code>装饰器就是为了在不修改被装饰对象源代码以及调用方式的前提下,为其添加新功能</code>
<code> </code><code>装饰器相当于闭包的实现</code>
<code> </code><code>例子:</code>
<code> </code><code>import</code> <code>time</code>
<code> </code><code>def</code> <code>timmer(func):</code>
<code> </code><code>def</code> <code>wrapper(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs):</code>
<code> </code><code>start_time </code><code>=</code> <code>time.time()</code>
<code> </code><code>res </code><code>=</code> <code>func(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs)</code>
<code> </code><code>stop_time </code><code>=</code> <code>time.time()</code>
<code> </code><code>print</code><code>(</code><code>"run time is {0}"</code><code>.</code><code>format</code><code>(stop_time </code><code>-</code> <code>start_time))</code>
<code> </code><code>return</code> <code>wrapper</code>
<code> </code>
<code> </code><code>@timmer </code><code>#相当于index = timmer(index)</code>
<code> </code><code>def</code> <code>index():</code>
<code> </code><code>time.sleep(</code><code>3</code><code>)</code>
<code> </code><code>print</code><code>(</code><code>"welcome to index"</code><code>)</code>
<code> </code><code>return</code> <code>1</code>
<code> </code><code>index() </code><code>#其实相当于执行了timmer(index)</code>
<code> </code><code>f </code><code>=</code> <code>timmer(index)</code>
<code> </code><code>print</code><code>(f)</code>
<code> </code><code>f() </code><code>#f()<=====>wrapper()</code>
<code> </code><code>认证用户登录</code>
<code> </code><code>login_user </code><code>=</code> <code>{</code><code>'user'</code><code>: </code><code>None</code><code>, </code><code>'status'</code><code>: </code><code>False</code><code>}</code>
<code> </code><code>def</code> <code>auth(func):</code>
<code> </code><code>if</code> <code>login_user[</code><code>'user'</code><code>] </code><code>and</code> <code>login_user[</code><code>'status'</code><code>]:</code>
<code> </code><code>res </code><code>=</code> <code>func(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs)</code>
<code> </code><code>return</code> <code>res</code>
<code> </code><code>else</code><code>:</code>
<code> </code><code>name </code><code>=</code> <code>input</code><code>(</code><code>"请输入姓名:"</code><code>)</code>
<code> </code><code>passwd </code><code>=</code> <code>input</code><code>(</code><code>"请输入密码:"</code><code>)</code>
<code> </code><code>if</code> <code>name </code><code>=</code><code>=</code> <code>"hyh"</code> <code>and</code> <code>passwd </code><code>=</code><code>=</code> <code>"123"</code><code>:</code>
<code> </code><code>login_user[</code><code>'user'</code><code>] </code><code>=</code> <code>"hyh"</code>
<code> </code><code>login_user[</code><code>'status'</code><code>] </code><code>=</code> <code>True</code>
<code> </code><code>print</code><code>(</code><code>"\033[45mlogin successful\033[0m"</code><code>)</code>
<code> </code><code>res </code><code>=</code> <code>func(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs)</code>
<code> </code><code>return</code> <code>res</code>
<code> </code><code>else</code><code>:</code>
<code> </code><code>print</code><code>(</code><code>"\033[45mlogin err\033[0m"</code><code>)</code>
<code> </code><code>@auth</code>
<code> </code><code>def</code> <code>index():</code>
<code> </code><code>print</code><code>(</code><code>"welcome to index page"</code><code>)</code>
<code> </code>
<code> </code><code>def</code> <code>home(name):</code>
<code> </code><code>print</code><code>(</code><code>"%s welcome to home page"</code> <code>%</code> <code>(name)) </code>
<code> </code><code>index()</code>
<code> </code><code>home(</code><code>"hyh"</code><code>)</code>
<code>5.</code><code>迭代器</code>
<code> </code><code>迭代器的概念: 重复上一次迭代的结果为下一次迭代的初始值,重复的过程称为迭代,</code>
<code> </code><code>每次重复即一次迭代</code>
<code> </code><code>为什么要有迭代器?</code>
<code> </code><code>对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式</code>
<code> </code><code>可迭代对象: 内置__iter__方法的都是可迭代对象</code>
<code> </code><code>[</code><code>1</code><code>,</code><code>2</code><code>].__iter__()</code>
<code> </code><code>'hello'</code><code>.__iter__()</code>
<code> </code><code>(</code><code>1</code><code>,</code><code>2</code><code>).__iter__()</code>
<code> </code><code>{</code><code>"a"</code><code>:</code><code>1</code><code>, </code><code>"b"</code><code>: </code><code>2</code><code>}.__iter__()</code>
<code> </code><code>{</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>}.__iter__()</code>
<code> </code><code>迭代器: 执行__iter__()方法,得到的结果就是迭代器,迭代器有__next__()方法</code>
<code> </code><code>i </code><code>=</code> <code>[</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>].__iter__()</code>
<code> </code><code>print</code><code>(i.__next__()) </code><code>#打印1</code>
<code> </code><code>print</code><code>(i.__next__()) </code><code>#打印2</code>
<code> </code><code>print</code><code>(i.__next__()) </code><code>#打印3</code>
<code> </code><code>print</code><code>(i.__next__()) </code><code>#抛出异常</code>
<code> </code><code>i__iter__() <</code><code>=</code><code>=</code><code>></code><code>iter</code><code>(i)</code>
<code> </code><code>i__next__() <</code><code>=</code><code>=</code><code>></code><code>next</code><code>(i)</code>
<code> </code><code>如何判断一个对象是可迭代对象,还是迭代器对象</code>
<code> </code><code>from</code> <code>collections </code><code>import</code> <code>Iterable, Iterator</code>
<code> </code><code>print</code><code>(</code><code>isinstance</code><code>(</code><code>'abc'</code><code>,Iterable))</code>
<code> </code><code>print</code><code>(</code><code>isinstance</code><code>([],Iterable))</code>
<code> </code><code>print</code><code>(</code><code>isinstance</code><code>((),Iterable))</code>
<code> </code><code>print</code><code>(</code><code>isinstance</code><code>({</code><code>'a'</code><code>:</code><code>1</code><code>},Iterable))</code>
<code> </code><code>print</code><code>(</code><code>isinstance</code><code>({</code><code>1</code><code>,</code><code>2</code><code>},Iterable))</code>
<code> </code><code>f</code><code>=</code><code>open</code><code>(</code><code>'a.txt'</code><code>,</code><code>'w'</code><code>)</code>
<code> </code><code>f.__iter__()</code>
<code> </code><code>print</code><code>(</code><code>isinstance</code><code>(f,Iterable)) </code><code>#只有文件是迭代器对象</code>
<code> </code><code>可迭代对象:只有__iter__方法,执行该方法得到的迭代器对象</code>
<code> </code><code>迭代协议:</code>
<code> </code><code>对象有__next__</code>
<code> </code><code>对象有__iter__,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身</code>
<code> </code><code>迭代器的优点和缺点</code>
<code> </code><code>优点:</code>
<code> </code><code>1.</code><code>提供了一种不依赖下标的迭代方式</code>
<code> </code><code>2.</code><code>就跌迭代器本身来说,更节省内存</code>
<code> </code><code>缺点:</code>
<code> </code><code>1.</code> <code>无法获取迭代器对象的长度</code>
<code> </code><code>2.</code> <code>不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退</code>
<code> </code>
<code>6.</code><code>生成器</code>
<code> </code><code>生成器函数: 只要函数体包含</code><code>yield</code><code>关键字,该函数就是生成器函数,生成器就是迭代器</code>
<code> </code><code>def</code> <code>foo():</code>
<code> </code><code>print</code><code>(</code><code>"first"</code><code>)</code>
<code> </code><code>yield</code> <code>1</code>
<code> </code><code>print</code><code>(</code><code>"second"</code><code>)</code>
<code> </code><code>yield</code> <code>2</code>
<code> </code><code>print</code><code>(</code><code>"third"</code><code>)</code>
<code> </code><code>yield</code> <code>3</code>
<code> </code><code>print</code><code>(</code><code>"fourth"</code><code>)</code>
<code> </code><code>g </code><code>=</code> <code>foo()</code>
<code> </code><code>for</code> <code>i </code><code>in</code> <code>g:</code>
<code> </code><code>print</code><code>(i)</code>
<code> </code><code>print</code><code>(</code><code>next</code><code>(g)) </code><code>#出发迭代器g的执行,进而出发函数</code>
<code> </code><code>print</code><code>(</code><code>next</code><code>(g))</code>
<code> </code><code>yield</code><code>的功能:</code>
<code> </code><code>1.</code><code>相当于为函数封装好__iter__和__next__函数</code>
<code> </code><code>2.return</code><code>只能返回一次值就终止了</code>
<code> </code><code>3.yield</code><code>能返回多次值,每次返回将函数暂停,下一次</code><code>next</code><code>从上一次暂停的位置继续</code>
<code> </code><code>模拟tail </code><code>-</code><code>f |grep </code><code>"python"</code>
<code> </code><code>例子:</code>
<code> </code><code>import</code> <code>time</code>
<code> </code><code>def</code> <code>tail(</code><code>file</code><code>):</code>
<code> </code><code>with </code><code>open</code><code>(</code><code>file</code><code>, encoding</code><code>=</code><code>'utf-8'</code><code>) as f:</code>
<code> </code><code>line </code><code>=</code> <code>f.readline().strip()</code>
<code> </code><code>if</code> <code>line:</code>
<code> </code><code>yield</code> <code>line</code>
<code> </code><code>else</code><code>:</code>
<code> </code><code>time.sleep(</code><code>0.2</code><code>)</code>
<code> </code><code>t </code><code>=</code> <code>tail(</code><code>'a.txt'</code><code>)</code>
<code> </code><code>for</code> <code>line </code><code>in</code> <code>t:</code>
<code> </code><code>print</code><code>(line)</code>
<code> </code>
<code> </code><code>def</code> <code>grep(pattern, lines):</code>
<code> </code><code>for</code> <code>line </code><code>in</code> <code>lines:</code>
<code> </code><code>if</code> <code>pattern </code><code>in</code> <code>line:</code>
<code> </code><code>yield</code> <code>line</code>
<code> </code><code>g </code><code>=</code> <code>grep(</code><code>"python"</code><code>, tail(</code><code>'one.py'</code><code>))</code>
<code> </code><code>print</code><code>(g)</code>
<code> </code><code>for</code> <code>i </code><code>in</code> <code>g:</code>
<code> </code><code>print</code><code>(i)</code>
<code> </code><code>yield</code><code>两种用法</code>
<code> </code><code>1.</code><code>语句形式: </code><code>yield</code> <code>1</code>
<code> </code><code>2.</code><code>表达式用法: x </code><code>=</code> <code>yield</code>
<code> </code><code>def</code> <code>deco(func):</code>
<code> </code><code>def</code> <code>wrapper(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs):</code>
<code> </code><code>next</code><code>(res) </code><code>#相当于res.send(None)初始化生成器</code>
<code> </code><code>return</code> <code>wrapper</code>
<code> </code><code>@deco</code>
<code> </code><code>def</code> <code>eater(name):</code>
<code> </code><code>print</code><code>(</code><code>"%s ready to eat"</code> <code>%</code><code>name)</code>
<code> </code><code>food_list </code><code>=</code> <code>[]</code>
<code> </code><code>while</code> <code>True</code><code>:</code>
<code> </code><code>food </code><code>=</code> <code>yield</code> <code>food_list</code>
<code> </code><code>food_list.append(food)</code>
<code> </code><code>print</code><code>(</code><code>'%s start to eat %s'</code> <code>%</code><code>(name, food))</code>
<code> </code><code>g </code><code>=</code> <code>eater(</code><code>'alex'</code><code>)</code>
<code> </code><code>v </code><code>=</code> <code>g.send(</code><code>"脚趾头"</code><code>) </code><code>#返回food_list列表</code>
<code> </code><code>print</code><code>(v) </code>
<code> </code><code>#send()函数发送数据给yield,跟next作用很相似,只是它能发送数据</code>
本文转自小白的希望 51CTO博客,原文链接:http://blog.51cto.com/haoyonghui/1928375,如需转载请自行联系原作者