zoukankan      html  css  js  c++  java
  • python之初识函数二

    装饰器

      1、什么是装饰器?

        不修改函数的调用方式,还能再原来函数的基础上增加功能。

      2、装饰器原则:开放封闭原则

        开放:对扩展时开放的

        封闭:对修改是封闭的

      3、装饰器的通用写法:

    def wrapper(func):  # 装饰器
        def inner(*args, **kwargs):  # 利用*args和**kwargs接受任意参数:位置参数和关键字参数
            ret = func(*args, **kwargs)  # 接收函数的返回值
            return ret
        return inner
    @wrapper  # 装饰器的重点:语法糖:这里实际上是wahaha = wrapper(wahaha),不过这样写应该写到定义的函数后
    def wahaha(a,b):   # 原函数
        sum = a + b
        return sum
    ret = wahaha(3, 4)  # 函数调用且接受返回值
    print(ret)

      ps:小知识补充一:time模块

    import time  # 导入time模块
    def wrapper(func):
        def inner(*args, **kwargs):
            start = time.time()  # time()可以查看当前时间(从1970到现在)
            ret = func(*args, **kwargs)
            end = time.time()
            print(end - start)  # 可以查看代码执行时间
            return ret
        return inner
    @wrapper
    def wahaha(a,b):
        sum = a + b
        time.sleep(0.1)  # 让代码停止0.1秒
        return sum
    # wahaha = wrapper(wahaha)
    ret = wahaha(3, 4)
    print(ret)
    View Code

      4、装饰器进阶

        完美装饰器

    import time
    from functools import wraps
    def wrapper(func):
        @wraps(func)  # 完美装饰函数
        def inner(*args, **kwargs):
            start = time.time()
            ret = func(*args, **kwargs)
            end = time.time()
            print(end - start)
            return ret
        return inner
    @wrapper
    def wahaha(a,b):
        sum = a + b
        time.sleep(0.1)
        return sum
    print(wahaha.__name__)  # 查看函数名

      5、带参数的装饰器

    import time
    from functools import wraps
    flag = 1  # 通过设置标志位可与以使用户更方便的决定用或不用装饰器
    def Flag(flag):  # 在原本装饰器的外层再套一层装饰器,进行一次参数的传递
        def wrapper(func):
            @wraps(func)
            def inner(*args, **kwargs):
                if flag:
                    start = time.time()
                    ret = func(*args, **kwargs)
                    end = time.time()
                    print(end - start)
                    return ret
                else:
                    ret = func(*args, **kwargs)
                    return ret
            return inner
        return wrapper
    @Flag(flag)
    def wahaha(a,b):
        sum = a + b
        time.sleep(0.1)
        return sum
    ret = wahaha(1,2)
    print(ret)
    View Code

      6、多个装饰器装饰同一个函数

    def wrapper1(func):  # 1
        def inner1(*args, **kwargs):  # 4
            print('before func inner1')  # 14
            ret1 = func(*args, **kwargs)  # 15 wahaha()  # 18 ret1 = 123
            print('after func inner1')  # 19
            return ret1  # 20
        return inner1  # 5
    def wrapper2(func):  # 2
        def inner2(*args, **kwargs):  # 8
            print('before func inner2')  # 12
            ret2 = func(*args, **kwargs)  # 13 inner1()  # 21 ret2 = ret1 = 123
            print('after func inner2')  # 22
            return ret2  #23
        return inner2  # 9
    @wrapper2  # 7 wrapper2(inner1)  # 10 wahaha = inner2
    @wrapper1  # 3 wrapper1(wahaha)  # 6 wahaha = inner1
    def wahaha():
        print('wahaha is good')  # 16
        return 123  # 17
    ret = wahaha()  # 11 inner2()  #24 ret = ret2 = 123
    print(ret)  # 25
    View Code

    迭代器

      1、双下方法:__iter__()加了双下划线的方法

      2、可迭代协议:只要含有__iter__方法的都是可迭代的   判断方法:'__iter__'in dir(方法名)

        可以被for循环的都是可迭代的

      3、迭代器协议:内部含有__iter__和__next__的方法就是迭代器    判断方法: '__iter__' in dir() and '__next__'in dir()

        可迭代的.__iter__()就得到一个迭代器

        迭代器中的__next__()方法可以一个一个的获取值

        for循环其实就是在使用迭代器

      4、迭代器的优点:

        (1)使用方便,一个迭代器只能从头到尾取值,且只能取一次

        (2)节省内存空间(可迭代对象是一个个给你而不是一次性读取,不会占用大块内存,每次只给一个)

    l = [1, 2, 3, 4, 5]
    g = l.__iter__()
    print(g.__next__())  # 每次返回列表中的一个值
    print(g.__next__())  # 每次返回列表中的一个值
    print(g.__next__())  # 每次返回列表中的一个值
    print(g.__next__())  # 每次返回列表中的一个值

    生成器

      1、本质上是一种迭代器,生成器与迭代器都是惰性运算

      2、生成器函数:本质上就是我们自己写的函数,只要含有yield的函数都是生成器函数,且yield不能与return共用,且只能在函数内使用

        生成器函数执行一次后获得一个生成器,此时函数并没有执行

      3、生成器:

       yield在返回值时和return有着相同的作用

    def generater():
        print(1)
        yield 'a'
        print(2)
        yield 'b'
    g = generater()  # 此时只是获得一个生成器
    ret = g.__next__()  # g.__next__()这时函数才真正执行,执行到第一个yield处
    print(ret)
    ret = g.__next__()  # g.__next__()函数接着上次停止的地方执行,执行到下一个yield处
    print(ret)

      因为生成器的本质是迭代器,所以一个生成器只能从头到尾取一次值,当取完值时在执行生成器.__next__()会报错

      4、从生成器中取值的几个方法:

        next、for循环、数据类型的强制转换(比较占用内存)

      5、生成器函数进阶一:send函数

    def generator():
        content = yield 1
        print('===',content)
        content = yield 2
        print('***',content)
        content = yield 3
    
    g = generator()
    ret = g.__next__()  # 在第一次使用生成器时,需用next获取到一个值
    print(ret)
    ret = g.send(10)  # send函数与next函数都有获取下一个值的效果,但send函数可以在上一个yield的地方传一个参数
    print(ret)
    ret = g.send(20)
    print(ret)
    ret = g.send(30)  # 最后一个yield不能接收外部的值
    print(ret)
    View Code

      6、生成器函数进阶二:获取移动平均值

    def average():
        sum = 0
        count = 0
        avg = 0
        while True:
            num = yield avg  # 生成器激活到这里就停止
            sum += num
            count += 1
            avg = sum/count
    a = average()
    a.__next__()  # 激活生成器
    a1 = a.send(10)  # 在停止位置给num传一个值
    a2 = a.send(20)
    print('%s,%s'%(a1,a2))
    View Code

      ps:小技巧

    def generator():
        a = 'asdfg'
        b = '12345'
        yield from a  # 可迭代类型数据都可以
        yield from b
    g = generator()
    for i in g:
        print(i)
    View Code

       7、生成器表达式

        1)列表推导式    

    list=['%s'%i for i in [1,2,3,4,5] if i>3]
    print(list)

        2)生成器表达式

    g = (i for i in range(10))
    for i in g:
        print(i)

        生成器表达式与列表推导式的括号不同,返回的值不同。生成器表达式返回的是一个生成器,几乎不占用内存。

        当碰到列表推导式相关面试题时,可以展开进行一步步的推导。

        3)字典推导式

    # 将字典的键值互换
    dic = {1:'a',2:'b'}
    dic1 = {dic[i]:i for i in dic}
    print(dic1)

        4)集合推导式

    set1 = {i**i for i in [1,-1,2]}
    print(set1)  # 集合自带去重功能
  • 相关阅读:
    Mithril – 构建杰出 Web 应用的 JS MVC 框架
    构建 iOS 风格移动 Web 应用程序的8款开发框架
    优秀设计:纹理在网页设计中的20个应用示例
    HTML5 Dashboard – 那些让你激动的 Web 技术
    免费下载!10套流行的扁平化界面设计素材
    另类网页设计:30个复古怀旧风格的网站作品
    2014年3月新鲜出炉的最佳 JavaScript 工具库
    25个最佳的 WordPress Gallery 画廊插件
    Gremlins.js – 模拟用户随机操作的 JS 测试库
    15款提高工作效率的 Web 项目管理工具
  • 原文地址:https://www.cnblogs.com/xfdhh/p/9863526.html
Copyright © 2011-2022 走看看