天天看點

python學習之函數學習進階

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>&gt;全局名稱空間</code><code>-</code><code>-</code><code>&gt;内置名稱空間</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()&lt;=====&gt;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__() &lt;</code><code>=</code><code>=</code><code>&gt;</code><code>iter</code><code>(i)</code>

<code>    </code><code>i__next__() &lt;</code><code>=</code><code>=</code><code>&gt;</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,如需轉載請自行聯系原作者