Python_Example_生成器 迭代器 闭包 装饰器 (重点) 学习/示例
Author: 楚格
2018-11-14 21:09:01
IDE: Pycharm2018.02 Python 3.7
KeyWord : 生成器 迭代器 闭包 装饰器
Explain:
----------------------------------------------
--
1 # coding=utf-8 2 # --------------------------------- 3 ''' 4 # Author : chu ge 5 # Function: 6 # 7 ''' 8 # --------------------------------- 9 ''' 10 迭代器: 11 迭代是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置对象。 12 迭代器对象从集合的第一个元素开始访问, 13 直到所有的元素被访问完结束。迭代器只能往前不会后退。 14 15 1.可迭代对象 16 以直接作用于for循环的数据类型有以下几种: 17 一类是集合数据类型,如,list,tuple,dict,set,str 18 一类是generator,包括生成器和带yield的generator function 19 这些可以直接作用于for循环的对象统称可迭代对象:iterable 20 21 2.判断是否可以迭代 22 可以使用isinstance()判断一个对象是否是iterable对象: 23 e.g 24 form collection import Iterable 25 isinstance([],Iterable) 26 >>true 27 而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值, 28 知道最后抛出stopiterable错误表示无法继续返回下一个值。 29 30 3迭代器 31 可以被next()函数调用并不断返回下一个值的对象为迭代器:iterable。 32 可以使用isinstance()判断一个对象是否是iterator对象: 33 form collection import Iterator 34 isinstance((x for x in range(10)),Iterator) 35 >>true 36 isinstance([],Iterator) 37 false 38 39 4.iter()函数 40 生成器都是iterator对象,但list,dict,str虽然是iterable,却不是iterator 41 把list,dict,str等iterable变成iterator可以使用iter()函数: 42 43 总结: 44 凡是可以作用于for循环对象的都是iterable类型: 45 凡是可作用于next()函数的对象都是iterator类型, 46 集合数据类型如list,dict,str等是iterable但不是iterator 47 不过可以通过iter()函数获得一个iterator对象。 48 49 50 》》》 51 52 53 闭包 54 55 1.函数引用 56 def line_conf(a,b): 57 def line(x): 58 :return a*x + b 59 :return line 60 61 line1 = line_conf(1,1) 62 line2 = line_conf(4,5) 63 print(line1(5)) 64 print(line2(5)) 65 66 2.什么是闭包 67 函数line与a,b构成闭包。 68 在创建闭包的时候,我们通过line_conf的参数a,b说明了二个变量的取值 69 这样,我们就确定了函数的最终形式(y = x + 1 和 y = 4x +5) 70 我们只需要变换参数a,b,就可以获得不同的直线表达函数。 71 由此,我们可以看到,闭包也具有提高代码可复用性的作用 72 73 如果没有闭包,我们需要每次创建直线函数的同时说明abx. 74 这样,我们就需要更多的参数传递,也减少了代码的可移植性。 75 1.闭包 优化了变量,原来需要类对象完成的工作,闭包也可以完成。 76 2.由于闭包引用了外部函数局部变量,则外部函数的局部变量没有及时释放,消耗内存 77 78 79 》》》 80 81 82 装饰器 83 1. 84 装饰器必须是闭包函数!! 85 1.1 86 def foo(): 87 Print("foo") 88 89 foo # 表示函数 90 f00() # 表示执行foo函数 91 92 1.2 93 def foo(): 94 print("foo") 95 foo = lambda x: x+1 96 foo() # 执行下面的lambda表达式,而不是原来的foo函数,因为foo这个名字 97 98 2. 99 写代码要循序,开发封闭原则 100 开放:对扩展开发 101 封闭:以实现功能代码块 102 代码可以增加,不能删除代码 103 104 # 闭包函数 105 def w1(func): 106 def inner(): 107 # 验证 1 108 # 验证 2 109 func() 110 return inner 111 112 语法糖:特殊功能 @ 113 @w1 114 def f1(): 115 print("f1") 116 117 @w1 118 def f2(): 119 print("f2") 120 121 举例 122 # 定义函数,完成包裹数据 123 def makeBold(fn): 124 print("1") 125 def wrapped(): 126 print("2") 127 print("----1----") 128 print("3") 129 print("cao1") 130 fn() 131 print("cao") 132 return "<b>" + fn() + "</b>" 133 print("4") 134 return wrapped 135 136 137 #定义函数:完成包裹数据 138 def makeItalic(fn): 139 print("5") 140 def wrapped(): 141 print("6") 142 print("----2----") 143 print("7") 144 return "<i>"+fn()+"</i>" 145 print("8") 146 return wrapped 147 148 # 只要python解释器执行到这个代码,那么就会自动的进行装饰 149 # 而不是等到调用的时候才装饰的 150 # @makeBold 151 # def test1(): 152 # print("test 1") 153 # return "hello 1" 154 # 155 # @makeItalic 156 # def test2(): 157 # print("test 2") 158 # return "hello 2" 159 160 @makeItalic 161 @makeBold 162 def test3(): 163 print("test 3") 164 return "hello 3" 165 166 167 168 print(test3()) 169 》》 170 1 171 4 172 5 173 8 174 6 175 ----2---- 176 7 177 2 178 ----1---- 179 3 180 cao1 181 test 3 182 cao 183 test 3 184 <i><b>hello 3</b></i> 185 186 187 188 4.装饰器功能 189 4.1引用日志 190 4.2函数执行统计时间 191 4.3执行函数前进行预处理 192 4.4执行函数后清理功能 193 4.5权限校验功能 194 4.6缓存 195 196 197 198 5装饰器实例 199 5.1函数 200 201 #不定长度到带参数 202 def func(functionName): 203 print("---func---") 204 # def func_in(aa,ss):# 固定参数 205 def func_in(*args,**kwargs): # 不定参数#*args元组**kwargs字典 206 print("---func_in----") 207 ret = functionName(*args,**kwargs) 208 return ret 209 print("---func2---") 210 return func_in 211 212 @func 213 def test(a,b): 214 print("---test-a=%d,b=%d--"%(a,b)) 215 return "hello" 216 这个例子包括:无参数,有参数和无固定参数和带返回值 217 218 #带参数通用装饰器 219 def func_arg(arg): #新增 220 print("--python--") 221 def func(functionName): 222 print("---func---") 223 # def func_in(aa,ss):# 固定参数 224 def func_in(*args,**kwargs): # 不定参数#*args元组**kwargs字典 225 print("---func_in----") 226 ret = functionName(*args,**kwargs) 227 return ret 228 print("---func2---") 229 return func_in 230 return func 231 232 @func_arg("cao") #新增 233 def test(a,b): 234 print("---test-a=%d,b=%d--"%(a,b)) 235 return "hello" 236 --- 237 a=test(11,23) 238 print(a) 239 》》 240 --python-- 241 ---func--- 242 ---func2--- 243 ---func_in---- 244 ---test-a=11,b=23-- 245 hello 246 247 ++++++++++++++++++++++++++++++++++++++++++++ 248 + end + 249 ++++++++++++++++++++++++++++++++++++++++++++ 250 #-------------------------------------------------------- 251 252 253 》》》 254 作用域 255 #globals\locals 256 def test(): 257 a = 100 258 b = 200 259 print(lo) 260 print(local) 261 262 LEGB规则 263 L:locals,当前所在命名空间 264 E:enclosing,外部嵌套函数的命名空间(闭包) 265 G:globals,全局变量 266 267 268 》》》 269 动态添加属性以及方法 270 271 动态语言:可以在运行的过程中,可以修改代码 272 静态语言:编译时已经确定好代码,运行时不能修改 273 274 为了达到限制实例属性,python允许定义class的时候, 275 定义一个特殊的__slots__变量,来限制该class实例能添加的属性。 276 即 277 class Person(object): 278 __slots__ = ("name",“age”) 279 280 ++++++++++++++++++++++++++++++++++++++++++++ 281 + end + 282 ++++++++++++++++++++++++++++++++++++++++++++ 283 #-------------------------------------------------------- 284 285 生成器 286 1.什么是生成器 287 通过列表生成式,可以直接创建一个列表。 288 但是,受到内存限制,列表容量肯定是有限的, 289 而且如果创建大容量的列表,但是访问特定几个,会造成空间浪费。 290 所以列表元素可以按照某种算法推算出来。 291 一边循环一遍计算的机制,成为生成器:generator 292 293 2.创建generator的方法1 294 只要把列表生成式[]改成() 295 L = [ x*2 for x in range(5)] # 列表 296 L 297 [0,2,4,6,8] 298 299 G = ( x*2 for x in range(5) )# 生成器 300 G 301 302 创建L和G的区别,仅在最外层的[]和(), 303 可以通过next()函数获得生成器的下一个返回值。 304 生成器保存的是算法,每次调用next(G),就计算出G的下一个元素的值, 305 直到计算到最后一个元素,没有更多的元素时,抛出stopiteration的异常。 306 for可以代替next 307 308 3.创建生成器方法2 309 generator非常强大,如果如果推算的算法比较复杂, 310 用类似列表生成式for无法实现时,可以用函数实现!! 311 312 4.send 313 314 生成器是这样一个函数,它记住上一次返回时在函数体中的位置。 315 对生成器函数的第二次或者第N次调用跳转至该函数中间,而上次调用的所有局部变量都保存不变。 316 317 生成器不仅记住了他的数据,还记住了他在流控制构造中的位置。 318 在命令编程中,这种构造不只是数据值。 319 生成器generator特点 320 1.节约内存 321 2.迭代到下一次的调用时候,所使用的参数都是第一次保留下来的, 322 即,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的。 323 324 325 326 327 328 329 330 331 332 333 334 335 336 ''' 337 338 ''' 339 # -------------------------------- 340 # 导入模块 341 # 1.系统库 342 # 2.第三方库 343 # 3.相关定义库 344 # -------------------------------- 345 ''' 346 # 1.系统库 347 import sys 348 import os 349 350 # 2.第三方库 351 352 ''' 353 # ------------------------------------------ 354 # 导入:同级不同文件夹 355 # 先文件夹__init__注释,其次引用name.py 356 # 最后 使用具体 类class 或者 函数function 名称 357 # ------------------------------------------ 358 ''' 359 360 ''' 361 # ------------------------------------------ 362 # 导入:同级同文件夹 363 # 先引用name.py 364 # 后 使用具体 类class 或者 函数function 名称 365 # ------------------------------------------ 366 ''' 367 368 ''' 369 # ============================================================================ 370 # Class : 类 371 # Explain : 输入参数 372 # : 输出参数 373 # ============================================================================ 374 ''' 375 376 ''' 377 # ============================================================================ 378 # Function: 379 # Explain : 输入参数 380 # : 输出参数 381 # ============================================================================ 382 ''' 383 384 385 386 387 # ============================================================================ 388 ''' 389 # ============================================================================ 390 # 测试专用 391 # ============================================================================ 392 ''' 393 if __name__ == "__main__":
--
--------------------------------------------
愿:
可以帮助到您,
感谢您的阅读。