Python中 生成器、迭代器、闭包、装饰器、元类

生成器(generator)
在Python中,这种一边循环一边计算的机制,称为生成器:generator。
创建生成器方法
1--根据列表推导式创建:第一种方法很简单,只要把一个列表推导式的 [ ] 改成 ( )
生成器保存的是算法,每次调用 next(生成器对象) 返回当前指针指向的元素,指针到头会报 StopIteration错误异常。还可以使用 for in循环,指针到最后不会报异常。
生成器的指针到最后不会返回(只能循环一便)。
2--在函数中使用 yield变成生成器
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,还可以用函数来实现。也可以用类中的方法来实现。
yield是一个关键词,类似return, 不同之处在于,yield返回的是一个生成器。
yield b  1、准备生成器 2、将b存放到生成器  3、返回有b元素的生成器 4、暂停
调用一下函数就会生成一个新的生成器
3.--在ipython3中导入模块方式使用
使用生成器
1、 next(生成器对象)2 、使用send  next(f)等价f.send(None)如果需要向函数中传递参数则使用f.send()。使用send()的时候第一次不能传递参数与其他或send(None)第二次就可以使用 3、使用生成器.__next__()方法 4、还可以使用for in循环,指针到最后不会报异常。
生成器的特点:
a.节约内存
b.迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的.
迭代器(Iterator):
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可迭代对象
1、集合数据类型,如 list 、 tuple(元组) 、 dict(字典) 、 set 、 str 等;
2、是 generator ,包括生成器和带 yield 的generator function。
这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 
可以使用 isinstance(对象, Iterable) 判断一个对象是否是 Iterable(可迭代的) 对象需要导包from collections import Iterator,还可以判断是否是某种类型isinstanse(对象,类型),判断是否为某对象的实例isinstanse(对象,类)
使用iter()函数把Iterable变成迭代器
生成器都是 Iterator(迭代器) 对象,但 list 、 dict 、 str 虽然是 Iterable(可迭代的) ,却不是 Iterator(迭代器) 。
把 list 、dict 、str 等 Iterable变成Iterator(迭代器)可以使用 iter(对象) 函数:
闭包定义:
1.闭包函数必须有内嵌函数;
2.内嵌函数需要引用该嵌套函数上一级namespace中的变量;
3.闭包函数必须返回内嵌函数;
通过这三点,就可以创建一个闭包;Python装饰器就是使用了闭包。
内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。
更改外部函数的不可变类型局部变量要加nonlocal+变量 声明变量
可变类型不用加nonlocal
装饰器
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器的作用就是为已经存在的对象添加额外的功能。 
用处:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计
变成装饰器:@装饰函数将函数(闭包)变成装饰器,装饰器要放在被装饰的函数前面
1、发现@装饰函数的声明,就会将下面的函数当作参数传递给装饰函数
2、装饰函数就会接收到参数,就会执行装饰函数
3、装饰函数将返回结果有返回给了被装饰的函数
执行的时候直接执行被装饰的函数就会看到被装饰后的结果
写代码要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展即:对扩展是开放的,而对修改是封闭的。
开放封闭原则主要体现在两个方面:
对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类或者函数内部进行任何修改。
般情况下为了让装饰器更通用,可以有return
装饰器带参数,在原有装饰器的基础上(三层函数嵌套)
1.先执行func_args("atguigu")这个函数,这个函数return的是func函数的引用      
2.@func,返回func_in的引用
3.使用@func对test进行装饰
装饰器带参数可以使其在运行的时候做不同的功能
类装饰器
装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在Python中一般callable对象都是函数,但也有例外。只要某个对象重写了 __call__() 方法,那么这个对象就是callable的。
class Test(object):
    def __init__(self, func):
        print("---初始化---")
        print("func name is %s"%func.__name__)
        self.__func = func
    def __call__(self):
        print("---装饰器中的功能---")
        self.__func()
#说明:#1. 当用Test来装作装饰器对test函数进行装饰的时候,首先会创建Test的实例对象#    并且会把test这个函数名当做参数传递到__init__方法中#    即在__init__方法中的func变量指向了test函数体##
#2.test函数相当于指向了用Test创建出来的实例对象#
#3. 当在使用test()进行调用时,就相当于让这个对象(),因此会调用这个对象的__call__方法
##4. 为了能够在__call__方法中调用原来test指向的函数体,所以在__init__方法中就需要一个实例属性来保存这个函数体的引用#    所以才有了self.__func = func这句代码,从而在调用__call__方法中能够调用到test之前的函数体
@Test
def test():
    print("----test---")
test()
多层的装饰器多个装饰器装饰一个函数
Python是动态语言
它是一类 在运行时可以改变其结构的语言 :例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。动态语言目前非常具有活力。
查看类中的属性dir
使用types.MethodType给对象添加带参数的函数 types.MethodType(方法名, 实例对象)
注意:P.run()这么直接调用,不会把self参数传递给run()方法所有报错,才会用types.MethodType(run, P)方式传递self也就是Pserson的实例P传递给run()中。
运行的过程中给类添加静态方法和类方法
往类里动态添加方法和属性都不需要使用types.MethodType()函数
运行的过程中删除属性、方法
删除的方法:
1. del 对象.属性名(方法名)
2. delattr(对象, "属性名")
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性,但类属性和类方法和静态方法可以添加
class Person(object):   
__slots__ = ("name","age") #对象的属性或方法名(只允许对象有name,age属性或方法)
__slots__只对当前类有作用对子类没有作用
元类1. 类也是对象
在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段。在Python中这一点仍然成立:类同样也是一种对象,也就是类对象。只要你使用关键字class,Python解释器在执行的时候就会创建一个对象。class关键词是创建对象的关键
1.你可以将它赋值给一个变量
2.你可以拷贝它
3.你可以为它增加属性
4.你可以将它作为函数参数进行传递
可以用hasattr(类,类属性名)判断是否有该属性,type可以知道类是什么类型的
使用type创建类
type还有一种完全不同的功能,动态的创建类。
type可以接受一个类的描述作为参数,然后返回一个类。(要知道,根据传入参数的不同,同一个函数拥有两种完全不同的用法是一件很傻的事情,但这在Python中是为了保持向后兼容性)
type可以像这样工作:
type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
Test=type("Test",(object,),{})  "Test"类名(object,)父级  {}类属性或者方法
添加的属性是类属性,并不是实例属性。
元类就是用来创建这些类(对象)的,元类就是类的类,这是因为函数type实际上是一个元类。type就是Python在背后用来创建所有类的元类。
对象.__class__与type相同可以查看对象的类或类是有谁创建的
__metaclass__属性
元类的主要目的就是为了当创建类时能够自动地改变类
就是通过在模块级别设定__metaclass__。采用这种方法,这个模块中的所有类都会通过这个元类来创建
但就元类本身而言,它们其实是很简单的:
1.拦截类的创建
2.修改类
3.返回修改之后的类
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值