学无止境

少年辛苦终身事,莫向光阴惰寸功。——唐·杜荀鹤《题弟侄书堂》


生成器、迭代器、闭包、装饰器

生成器


  • 在python中,这种一边循环一边计算的机制,称为生成器generator
  • 列表推导式
  • generator=(x for x in range())
  • next(生成器对象)—》返回当前指针指向的元素
  • 如果使用next方法获取元素的话,取到最后一个元素的时候就会报错(stopIteration)
  • 生成器获取元素的两种方式:
  •  1、next(generstor)-->返回元素
    
  •  2、for x in gen
    
  •      print(x)
    
  • 区别:for in 到头不会报异常
  • next到头会包异常stopIteration
    
  • 创建生成器方法2—在函数中yield
  • 函数生成追著名的斐波拉契数列
  •  def fibonacci(num):
    
  •       a,b=0,1
    
  •       i=0
    
  •       while i<num:
    
  •           a,b=b,(a+b)
    
  •           i+=1
    
  •           print(b)
    
  •   fibonacci(10)
    

  • 使用yield变成生成器

  •  def fibonacci(num):
         a,b=0,1
      	i=0
      	while i<num:
      	yield b
      	a,b=b,(a+b)
      	i+=1
      	#print(b)
     f=fibonacci(10)
     print(f)
    
  • yield b
  • 1:准备生成器
  • 2,将B存放到生成器
  • 3.返回有b元素的生成器
  • 4,返回就暂停
  • yield产生生成器,使用Next拨动指针

  • 常用方法

  • next()同send(None)
  • 如果需要向你的函数中传递参数则使用send(“参数”)
  • f.__ next__()也能调用
  • 注意:使用send的时候不能第一次传递参数但第一次可以传递None,也可以先调用next或者.__ next__()后再调用send方法
  • ==注意捕获异常==
  • 多任务的生成器

  • 多任务的生成器
  • 生成器好处

  • a.节约内存
  • b.迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留下的,而不是新创建的

  • 迭代器


  • 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
  • 迭代器只能往前
  • 可迭代对象

  • 直接作用与for循环的数据类型有一下集中。
  • 一类时几何数据类型,如List、tuple、dictionary、set、str等
  • 用判断isinstance()判断是否可以迭代

  • 1.判断是否是某种类型
  • isinstance(变量,str,list,dic,set,tuple)
  • 导包
  • from collections from Iterator
    
  • print(isinstance(list1,Iterable))
    
  • 判断是否为迭代类型
    
  • from collections from Iterator
    
  • isinstance (str,Iterator)
    
  • ==判断是不是迭代器==
    
  • 使用iter()函数把Iterable变成迭代器

  • 生成器都是Iterator(迭代器)对象,但lit,dict.str虽然是Iterable(可迭代的),却不是迭代器
  • print(isinstance(iter(str),Iterator))
    
  • it = iter(ss)
    
  • print(next(it))
    
  • print(if.__next__())
    
  • 总结:
  • 凡是可作用于 for 循环的对象都是 Iterable 类型;
  • 凡是可作用于 next() 函数的对象都是 Iterator 类型;
  • 集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象

闭包


  • 闭包函数必须有内嵌函数
  • 内嵌函数需要引用该嵌套函数上一级namespace中的变量
  • 闭包函数必须返回内嵌函数
  • 通过这三点就可以创建一个闭包
  • • Python装饰器就是使用了闭包。
  • 闭包的好处,使代码变得简洁。
  • 内部函数对外部函数作用域里变量的引用

  • 如果内嵌函数i想使用外侧函数的变量就使用nonlocal
  • 对于不可变类型使用Nonlocal
  • 1.当内嵌函数内部要修改外侧函数的不可变类型的值需要在内嵌函数中添加nonlocal
  • 可变类型的nonlocal是可加可不加

装饰器


  • 理解成:丰富一个原有函数,使用装饰器
  • 依赖的是闭包
  • @xxx
  • 发现有一个”标记"@xxx
  • 自动将@x’x’x下方紧挨这的函数作为参数传递给xxx函数,
  • xxx函数收到参数,则进入函数体执行
  • 最后装饰器返回的结果最后给了@xxx下面的函数,如果想看装时后的效果直接调用@xxx下面的函数就行了
  • @函数名是python的以中国语法糖
  • 装饰器(decorator)功能-统计方法的执行

  • time.time() 返回当前时间的时间戳(1970纪元后经过的浮点秒数


  • 装饰器示例

  • 无参数的函数:
  • 有参数的函数不要忘记穿参如果是不定长参数需要加*解包
  • 装饰器带参数,在原有装饰器的基础上
  • 类装饰器
  • 装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在python中一般callable对象都是函数,但也有例外,只要摸个对象重写了__ caa__方法,那么这个对象就是callable的。
  • __ call__
  • 多次装饰
  • 如果函数要进行多次装饰,则里最近的首先进行装饰

  • 动态语言


  • 动态添加

  • import types

  • types.MethodType(函数,对象)

  • 运行过程中删除

  • del 对象.属性名

  • delattr(对象,‘属性名’)

  • 使用__slots__限制添加实例属性和实例方法,但类属性和类方法和静态方法可以添加

  • _slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

  • 不限制类的属性或者方法(静态方法)

  • 只能限制对象的属性或者方法

  • _slots__只是对当前类起作用,但是不会影响子类


元类


  • 在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段。++在Python中这一点仍然成立:++
  • 判断类中有没有属性
  • hasattr(类名,属性名)
  • 动态的创建类
  • 类同样也是一种对象,也就是类对象。只要你使用关键字class,Python解释器在执行的时候就会创建一个对象。
    1. 你可以将它赋值给一个变量
  1. 你可以拷贝它
  2. 你可以为它增加属性
  3. 你可以将它作为函数参数进行传递
  • 因为类也是对象,有可以在运行时动态的创建它们,就像其他任何对象一样。首先,可以在函数中创建类,使用class关键字即可。
  • 当你使用class关键字时,Python解释器自动创建这个对象。
  • 使用type创建类

  • type还有一种完全不同的功能,动态的创建类。
  • type可以像这样工作:
  • type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
  • 使用type创建带有属性的类

  • type的第2个参数,元组中是父类的名字,而不是字符串。 添加的属性是类属性,并不是实例属性。
  • 使用type创建带有方法的类

  • 如果创建实例函数调用动态静态方法要加self
  • 到底什么是元类

  • type就是元类
  • 元类就是创建类这种对象的东西,type就是python的内奸元类,当然了,你也可以创建自己的元类

  • __ metaclass__属性


  • 可以创建一个类的东西
  • def aa(参数一:类名,2:父类,3:属性)
  • return type(1,类名2,父类,3,新属性)
  • 自定义元类

  • 拦截类的创建
  • 修改类
  • 返回修改之后的类