Python学习之三大名器-装饰器、迭代器、生成器


Python学习之三大名器-装饰器、迭代器、生成器

一、装饰器

    装饰,顾名思义就是在原来的基础上进行美化及完善,器这里指函数,所以说装饰器就是装饰函数,也就是在不改变原来函数的代码及调用方式的前提下对原函数进行功能上的完善。其核心原理其实是利用闭包。

    格式 @关键字+装饰函数

         被装饰函数() 

    注意:@行必须顶头写而且是在被装饰函数的正上方

    按照形式可以分为:无参装饰器和有参装饰器,有参装饰器即给装饰器加上参数

    以下示例是一个无参装饰器,为原函数添加了统计运行时间的功能

import time
#定义装饰器 
def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print("run time is %s" %(stop_time-start_time))
        return res
    return wrapper
 

#调用装饰器
@timer
def index():
    l = []
    for i in range(10000000):
        l.append(i)
#调用阶段 
index()

   以下是一个有参装饰器,实现简单的认证功能,#数字表示程序依次执行顺序

def auth2(auth_type): #1 #3
    def auth(func): #4 #6
        def wrapper(*args,**kwargs): #7 #10
            if auth_type == ‘file‘: #11
                name=input(‘username: ‘)
                password=input(‘password: ‘)
                if name == ‘zhejiangF4‘ and password == ‘666‘:
                    print(‘auth successfull‘)
                    res=func(*args,**kwargs)
                    return res
                else:
                    print(‘auth error‘)
            elif auth_type == ‘sql‘: #12
                print(‘nothing!‘) #13
        return wrapper #8
    return auth #5
 
@auth2(auth_type=‘sql‘) #2
def index():
    print(‘welcome to inex page‘)

 index() #9

二、迭代器

    迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。------百度百科

    可迭代的:只要对象本身有__iter__方法,那它就是可迭代的

    执行对象下的__iter__方法,得到的结果就是迭代器

       

为什么要用迭代器:
    优点
    1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索 引的可迭代对象了(字典,集合,文件)
    2:迭代器与列表比较,迭代器是惰性计算的,更节省内存

缺点:
    1:无法获取迭代器的长度,使用不如列表索引取值灵活
    2
一次性的,只能往后取值,不能倒着取值

查看s对象是否是迭代器:print(isinstance(s,Iterator)) 返回True就是迭代器

from collections import Iterable,Iterator
s=‘hello‘
l=[1,2,3]
t=(1,2,3)
d={‘a‘:1}
set1={1,2,3,4}
f=open(‘a.txt‘)
s.__iter__()
l.__iter__() 
t.__iter__()
d.__iter__()
set1.__iter__()
f.__iter__()
print(isinstance(s,Iterable))
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(set1,Iterable))
print(isinstance(f,Iterable))

print(isinstance(s,Iterator))
print(isinstance(l,Iterator))
print(isinstance(t,Iterator))
print(isinstance(d,Iterator))
print(isinstance(set1,Iterator))
print(isinstance(f,Iterator))

运行结果如下:

可以看出,字符串、列表、字典、集合、元组、文件都是可迭代的,但是只有文件是迭代器

三、生成器

    

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

    函数中包含yield语句的我们称其为生成器函数

    yield与return有何区别?
        return只能返回一次函数就彻底结束了,而yield能返回多次值
    yield到底干了什么事情:
        yield把函数变成生成器(生成器就是迭代器)
        函数在暂停以及继续下一次运行时的状态是由yield保存

    下例是两个生成器的应用,一个用来不断的输入url,不断的解析,另外一个则模仿Linux中的管道命令(实质是将一个函数的运行结果传给下一个函数做处理,实现的比较简单粗暴,多包涵,哈哈)

例1:

from urllib.request import urlopen
def get(url):
    while True:
        def index():
            return urlopen(url).read()
        url = yield index()
g = get(‘http://www.baidu.com‘)
next(g)
def run():
    while True:
        url = input("请输入URL:")
        if ‘http://‘ not in url:
            print(g.send(‘http://‘+url))
        else:
            print(g.send(url))
run()

例2:

def cat(filename):
    with open(filename,‘r‘) as f:
        while True:
            line = f.readline()
            if not line:
                break
            else:
                yield line
def grep(string,lines):
    for line in lines:
        if string in line:
            yield line
g1 = cat(‘a.txt‘)
g2 = grep(‘mac‘,g1)
if __name__ == ‘__main__‘:
    m = input("请输入命令:").strip()
    if m == "cat a.txt |grep mac":
        for i in g2:
            print(i)

补充:协程

    如果在一个函数内部yield的使用方式是表达式形式的话,如x=yield,那么该函数成为协程函数

直接看例子吧

def hello(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        next(res)
        return res
    return wrapper

@hello
def eater(name):
    print(‘%s start to eat food‘ %name)
    food_list=[]
    while True:
        food=yield food_list
        print(‘%s get %s ,to start eat‘ %(name,food))
        food_list.append(food)
    print(‘done‘)
e=eater("somebody")
print(e.send(‘巧克力‘))
print(e.send("香蕉"))

时间: 2024-11-03 22:02:04

Python学习之三大名器-装饰器、迭代器、生成器的相关文章

函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数def max(x,y): if x>y: return x else: return ydef max1(a,b,c,d): res=max(a,b) res2=max(res,c) res3=ma

python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式

本节课重要知识点内容如下: 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式 1.函数嵌套 函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数 def bar(): print('from nbar')def foo(): print('from foo') bar()foo()def max2(x,y): if x > y: return x else: return ydef max4(a,

<04day>_函数嵌套--闭包函数--装饰器--迭代器--生成器

一.函数的嵌套定义 1.python函数支持嵌套 def f1(): #f1函数的定义 def f2(): #f2函数的定义 print('from f2') def f3(): #f3函数的定义 print('from f3') f2() f1() 嵌套函数--运行结果说明: 1首先调用f1()结果,f1函数为空.担保函f2函数,f2函数有内容打印并且有调用,f2函数包含f3函数,但f3函数无调用. 运行结果: 列子:多个数据之间的大小比较. #!/usr/bin/python # -*- c

Python学习---装饰器/迭代器/生成器的学习【all】

Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210 原文地址:https://www.cnblogs.com/ftl1012/p/9484145.html

python学习笔记7:装饰器

一.什么是装饰器 装饰器,它本身是一个函数. 装饰器的作用在于,在不改变现有函数的调用方式的前提下,给其新增一些功能:这些功能一般都是公用的. 它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权限校验等场景.(此句引用:https://zhuanlan.zhihu.com/p/25648515) 二.学装饰器的前提知识 1.函数即变量 2.高阶函数 3.函数嵌套 以上三个知识点,在我的上一篇博客'python学习笔记6:函数'里 有详细介绍,这里不赘述 三.一个例子 1.场

python第四天装饰器+迭代器+生成器

1.函数嵌套:在调用一个函数的过程中,调用了其他函数 def f1(): x=1 def f2(): print('from f2') f2() f1()  2.名称空间与作用域 a. 名称空间:存放名字与变量值绑定关系的地方 (1)内置名称空间:在python解释器启动时产生,存放一些python内置的名字 (2)全局名称空间:在执行文件时产生,存放文件级别定义的名字. (3)局部名称空间:在执行过程中,如果调用了该函数则会产生该函数的局部名称空间.在调用该函数的时候生效,调用结束时失效 加载

python 学习笔记7(装饰器)

闭包(closure)是函数式编程的重要的语法结构. 定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). def outer(): x = 1 def inner(): print(x) return inner f = outer() f() inner就是内部函数,inner里引用了外部作用域的变量x(x在外部作用域outer里面,不是全局作用域),则这个内部函数inner就是一个闭包. 闭包=函数块+定义函数时的环

Python学习之路7?装饰器

一:命名空间与作用域 1.1命名空间 局部命名空间: def foo(): x=1 def func(): pass 全局命名空间: import time class ClassName:pass def foo():pass 内键命名空间: sum,max,min 等 python加载三个命名空间的顺序: 1.内键命名空间 2.全局命名空间:文件级别的或叫做模块级别的 3.局部命名空间:只有调用函数的时候才会加载,函数调用结束就被释放掉 1.2作用域 全局作用域: 1 同时x=1为全局变量

python学习进度14(装饰器)

由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25') ... >>> f = now >>> f() 2015-3-25 函数对象有一个__name__属性,可以拿到函数的名字: >>> now.__name__ 'now' >>> f.__name__ 'now' 现在,假设我们要增强now()函数的功能,比如