• python基础-装饰器,生成器和迭代器


    学习内容

      1.装饰器

      2.生成器

      3.迭代器

      4.软件目录结构规范

    一:装饰器(decorator)

    1.装饰器定义:本质就是函数,用来装饰其他函数,即为其他函数添加附加功能。

    2.装饰器原则:1)不能修改被装饰函数的源代码2)不能修改被装饰函数的调用方式

    3.装饰器的知识储备

      1)函数即是变量

      2)高阶函数:a,把一个函数名当作实参给别外一个函数(在不修改被装饰函数源代码的情况下实现增加附加功能)

            b,返回值中包括函数名(不修改函数调用方式)

      3)嵌套函数:用def 在别外的函数中定义的函数

      装饰器=高阶函数+嵌套函数

    4.装饰器使用:1)被装饰函数不带参数2)被装饰函数带有参数3)装饰多个函数,根据被装饰函数不同,增加不同的装饰功能。

      1)实现被装饰函数不带参数代码

        三个页面,index不需要登陆,home,bbs页面需要登录

         

    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'
    """
    实现被装饰函数不带参数代码
    """
    def login(func): #传递函数标识
        def wrapper():  #函数嵌套
            print("实现登陆")
    
            func() #执行函数
        return wrapper #返回函数标识
    
    
    def index():
        print("you in the index page")
    
    @login  #@login=(home=login(home))
    def home():
        print("you in the home page")
    
    @login
    def bbs():
        print("you in the bbs page")
    
    index()
    home()
    bbs()

      2)实现被装饰函数带参数代码

        三个页面,index不需要登陆,home,bbs页面需要登录

    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'
    """
    实现被装饰函数带参数代码
    """
    def login(func): #传递函数标识
        def wrapper(*args,**kwargs):  #函数嵌套,传递被装饰函数的参数
            print("实现登陆")
    
            func(*args,**kwargs) #执行函数
        return wrapper #返回函数标识
    
    
    def index(name):
        print("%s in the home page" %name)
    
    @login  
    def home(name):
        print("%s in the home page" %name)
    
    @login
    def bbs(name):
        print("%s in the home page" %name)
    
    index("shisan")
    home("shisan")
    bbs("shisan")

      2)装饰多个函数,根据被装饰函数不同,增加不同的装饰功能。

        三个页面,index不需要登陆,home,bbs页面需要登录

    
    
    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'
    """
    装饰多个函数,根据被装饰函数不同,实现不同的装饰功能
    """
    #嵌套三层函数
    def login(flag): #传递类型
    def out_wrapper(func):#传递函数标识
    def wrapper(*args,**kwargs): #函数嵌套,传递被装饰函数的参数
    if flag=="home":
    print("实现home装饰")
    else:
    print("实现bbs装饰")

    func(*args,**kwargs)
    return wrapper
    return out_wrapper


    def index(name):
    print("%s in the home page" %name)

    @login(flag="home")
    def home(name):
    print("%s in the home page" %name)

    @login(flag="bbs")
    def bbs(name):
    print("%s in the home page" %name)

    index("shisan")
    home("shisan")
    bbs("shisan")
     

    二.生成器

      列表生成式,例如:[x for i in range(10)]

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

      生成器(generator):通过一边循环一边生成机制就生成器.

      生成器只有在调用时才会生成相应的数据,只记录当前的位置

      创建生成器方法 一是:(x for i in range(10))二是:如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

        [x for i in range(10)]是列表

        (x for i in range(10))是generator

        generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误

        python2中是next() python3中是__next__()

        创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误

      生成器示例代码

      

    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'
    
    l=[x*2 for x in range(10)] #列表生成式
    print(l)
    
    g=(x*2 for x in range(3)) #创建生成器方式一
    print(g) #提示是generator
    
    # print(g.__next__()) #访问方式一是通过高用__next方法
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__()) #访问抛出异常StopIteration
    
    # g=(x*2 for x in range(3))
    # for i in g:  #通过for访问是没有异常的
    #     print(i)
    
    # #捕获StopIteration方式
    while True:
        try:
            print(g.__next__())
        except StopIteration as e:
            print("generator except:%s" %e.value)
            break

      通过yeild生成generator

      

    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'
    
    def fib(max):#斐波拉契数列
        n,a,b=0,0,1
        while True:
            yield b
            a,b=b,a+b #t=(b,a+b) a=t[0],b=t[1]
            n+=1
            if n>max:
                break
    
        return "done"
    
    f=fib(10)
    while True:
    
        try:
            print(f.__next__())
        except StopIteration as e:
            print("generator stop" ,e.value)
            break

     三.迭代器

      可以直接用于for循环的对象就迭代对象:Iterable。集合类list,set,dict,str,tuple;generator类生成器和带yield的generator function

      可以使用isinstance()判断是对象是不是迭代对象。

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

      把listdictstrIterable变成Iterator可以使用iter()函数

      Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算

      凡是可作用于for循环的对象都是Iterable类型;

      凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

      集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

      Python的for循环本质上就是通过不断调用next()函数实现的

    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'
    
    from collections import Iterable,Iterator
    
    #可迭代对象
    print(isinstance([],Iterable)) 
    print(isinstance((),Iterable))
    print(isinstance((x for x in range(10)),Iterable))
    #迭代器
    print(isinstance([],Iterator))
    print(isinstance((),Iterator))
    print(isinstance((x for x in range(10)),Iterator))
    #用iter()转换为迭代器
    print(isinstance(iter([]),Iterator))
    print(isinstance(iter(()),Iterator))
    print(isinstance((x for x in range(10)),Iterator))
    

      四.目录组织方式

      例子:

    假设你的项目名为foo, 比较建议的最方便快捷目录结构这样就足够了:

    Foo/
    |-- bin/
    |   |-- foo
    |
    |-- foo/
    |   |-- tests/
    |   |   |-- __init__.py
    |   |   |-- test_main.py
    |   |
    |   |-- __init__.py
    |   |-- main.py
    |
    |-- docs/
    |   |-- conf.py
    |   |-- abc.rst
    |
    |-- setup.py
    |-- requirements.txt
    |-- README
    

    简要解释一下:

    1. bin/: 存放项目的一些可执行文件,当然你可以起名script/之类的也行。
    2. foo/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py
    3. docs/: 存放一些文档。
    4. setup.py: 安装、部署、打包的脚本。
    5. requirements.txt: 存放软件依赖的外部Python包列表。
    6. README: 项目说明文件。
  • 相关阅读:
    Ajax_原生ajax写法、理解异步请求、js单线程+事件队列、封装原生ajax
    Ajax_实现动态网站的技术、php语法、php接口、前端渲染和后端渲染
    Ajax_Apache访问资源文件的权限配置、资源存放路径配置、配置虚拟主机、动态网站静态网站区别
    Ajax_Ajax、客户端、服务器端的认识与比较、服务器环境的搭建wamp
    jquery_jquery插件、jqueryUI使用方法、自定义jquery插件(一个插件其实就是一个功能)
    jquery_jquery事件绑定和解绑、链式编程、jquery中的主动遍历each、多库共存
    jquery_jquery动态创建元素及应用
    jquery_jquery动画
    jquery_jquery样式操作、链式编程
    jquery_认识jquery好处、选择器、小案例
  • 原文地址:https://www.cnblogs.com/lixiang1013/p/6817089.html
Copyright © 2020-2023  润新知