Python-函数的各种器

  Python中的各大器,方便函数的使用,新增函数的方法和用途

一、装饰器

  定义:在原有的函数前后,增加功能,且不改变原函数的调用方式

  

def wrapper(f1):
    '''
使用闭包函数用于装饰器的原因是:不想修改原函数的调用方式
    '''
    def inner(*args,**kwargs):
        '''执行函数之前的操作'''
        ret = f1(*args,**kwargs)
        '''执行函数之后的操作'''
        return ret
    return inner

#使用装饰器wrapper的方式为
@wrapper
def  func():
    pass

注:在装饰器中的返回值,只能用一个变量将内部的函数返回值接收,如果直接返回函数的返回值,会导致多次执行装饰函数

装饰器的进阶

1、控制装饰器

#需求:控制装饰器的开启和关闭
FLAG=True  #全局变量,控制是否开启装饰器
def outer(flag):
    def wrapper(f1):
        def inner(*args,**kwargs):
            if flag:
                '''执行函数之前的操作'''
                ret = f1(*args,**kwargs)
                '''执行函数之后的操作'''
            else:
                ret = f1(*args, **kwargs)
            return ret
        return inner
    return  wrapper

@outer(FLAG)
def fun():
    pass

2、多个装饰器,装饰函数

def wrapper1(func):
    def inner():
        print('wrapper1 ,before func')
        func()
        print('wrapper1 ,after func')
    return inner

def wrapper2(func):
    def inner():
        print('wrapper2 ,before func')
        func()
        print('wrapper2 ,after func')
    return inner

@wrapper2
@wrapper1
def f():
    print('in f')

f()
#结果是wrapper2
wrapper1

wrapper1

wrapper2
 

二、迭代器

引入:

  如何从列表和字典中取值

    index索引

    for循环

凡是可以使用for循环取值的都是可迭代的

可迭代协议:内部含有__iter__方法的都是可迭代的

迭代器协议:内部含有__iter__方法和__next__ 方法的都是迭代器

  next方法:只取出当前位置和下一个位置的值

迭代器的优势:1、节省内存,2、用时快:取一个值,就可以进行运算,不用取出所有值,再进行计算

range在py2和py3的区别:

  py2中:不管range多少,会生成一个列表,这个列表来存储所有生成的值

  py3中:不管range多少,都不会实际的生成任何一个值

迭代器的特性:惰性运算

对迭代器的判断:

from collections import Iterator   
print(isinstance(range(100000000),Iterator))  #验证range执行之后得到的结果不是一个迭代器

三、生成器

  自己写的迭代器就是一个生成器

  两种自己写生成器(迭代器)的机制:生成器函数  生成器表达式

  凡是带有yield的函数,就是一个生成器函数

def func():
    print("#####")
    yield  1
    print("%%%%%%")
    yield 2  #记录当前所在位置,等待下次next来触发函数的状态

g=func()
print("```",next(g))
print("```",next(g))
#生成器的调用执行函数代码的,只返回一个生成器(迭代器)
#想要生成器函数执行,需要用next来调用
#yield是个关键字,作用类似return,但是区别于return,yield在函数的执行过程中遇到后,只会暂停函数的运行,
存入到内存中,但是不会将函数终止释放,当下次调用next方法的时候,会在从yield的位置继续运行,并且yield还
可以赋值给变量,并接收send传入的值
#在生成器中传入参数
#计算输入值后的平均值
def  average():
    sum_money=0
    day=0
    avg=0
    while True:
        money = yield  avg
        sum_money += money
        day += 1
        avg = sum_money / day
g = average()
next(g)

print(g.send(200))
print(g.send(300))
计算平均值

   注:send必须在next方法后运行,不能直接使用

  

原文地址:https://www.cnblogs.com/fan-yi/p/8906086.html