zoukankan      html  css  js  c++  java
  • python 装饰器、列表生成式、生成器、迭代器

    # 作用域
    # 高阶函数
    # 闭包

    # 闭包(closure)是函数式编程的重要的语法结构。

    # 定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).

    # 闭包=函数块+定义函数时的环境,inner就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x


    # def outer():
    # x = 1
    #
    # def inner():
    # b = 6
    # print(x)
    #
    # return inner
    #
    #
    # # inner()#报错原因:找不到这个引用变量
    # in_func = outer() # 这里其实就是一个变量赋值,inner的引用对象赋值给in_func,类似于a=5,b=a一样
    # # 有同学会想直接赋值不行吗:in_func=inner? ,inner不还是找不到吗,对吧
    # in_func()



    # 装饰器(函数)decrator

    # 必须遵守开放封闭原则

    #*******************************************
    import time


    def show_time(func): #装饰器函数
    def wrapper():
    start_time = time.time()
    func()
    end_time = time.time()
    print('spend %s' % (end_time - start_time))

    return wrapper


    def foo():
    print('hello foo')
    time.sleep(3)


    foo = show_time(foo)
    foo()

    #******************************************

    import time


    def show_time(func): #装饰器函数
    def wrapper():
    start_time = time.time()
    func()
    end_time = time.time()
    print('spend %s' % (end_time - start_time))

    return wrapper


    @show_time # foo=show_time(foo)
    def foo():
    print('hello foo')
    time.sleep(3)


    @show_time # bar=show_time(bar)
    def bar():
    print('in the bar')
    time.sleep(2)


    foo()
    print('***********')
    bar()

    #**************************************


    #带参数的装饰器函数

    import time


    def show_time(func):
    def wrapper(a, b):
    start_time = time.time()
    func(a, b)
    end_time = time.time()
    print('spend %s' % (end_time - start_time))

    return wrapper


    @show_time # add=show_time(add)
    def add(a, b):
    time.sleep(1)
    print(a + b)


    add(2, 4)

    #********************************************


    #不定长参数
    #***********************************不定长参数
    import time

    def show_time(func):

    def wrapper(*args, **kwargs):
    start_time = time.time()
    func(*args, **kwargs)
    end_time = time.time()
    print('spend %s'% (end_time-start_time))

    return wrapper

    @show_time #add=show_time(add)
    def add(*args, **kwargs):

    time.sleep(1)
    sum=0
    for i in args:
    sum += i
    print(sum)

    add(2,4,8,9)

    #*********************************************


    #装饰器参数

    import time


    def time_logger(flag=0):
    def show_time(func):
    def wrapper(*args, **kwargs):
    start_time = time.time()
    func(*args, **kwargs)
    end_time = time.time()
    print('spend %s' % (end_time - start_time))

    if flag:
    print('将这个操作的时间记录到日志中')

    return wrapper

    return show_time


    @time_logger(3)
    def add(*args, **kwargs):
    time.sleep(1)
    sum = 0
    for i in args:
    sum += i
    print(sum)


    add(2, 7, 5)

    #
    # @time_logger(3) 做了两件事:
    # 1time_logger(3):得到闭包函数show_time,里面保存环境变量flag
    # 2@show_time addshow_time(add)
    # 上面的time_logger是允许带参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器(一个含有参数的闭包函数)。当我 们使用@time_logger(3)调用的时候,Python能够发现这一层的封装,并把参数传递到装饰器的环境中。





    # 列表生成式

    # a = [x*2 for x in range(10)] #X先遍历在赋给x*2的结果列表形式顺序不变
    #
    # print(a) #[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

    # **********************************************

    # def f(n):
    # return n**3
    # a = [f(x) for x in range(10)]
    # print(a) #[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]

    # ***********************************************




    # 生成器 generator

    # s = (x*2 for x in range(10))
    #
    # print(s) #<generator object <genexpr> at 0x000002560584AC80>
    #
    # print(s.__next__()) #内部特殊方法一般不建议使用
    #
    # print(next(s)) #等价于调用s.__next__() py2: s.next()



    # 生成器就是一个可迭代对象 Iterable

    # for i in s: # s就是一个迭代对象
    # print(i)


    # 生成器2种创建方式:
    # 1 s = (x*2 for x in range(10))
    # 2 yield


    # def foo():
    # print('ok')
    # yield 1
    # foo() #没有执行,说明foo()就是一个生成器对象
    # next(foo()) # 这样才能进去并执行,结果打印:ok

    # 什么是可迭代对象:iter

    # l = [1,2,3]
    # l.__iter__()
    # print(l)

    # 生成器执行:next() , send()

    def bar():
    print('ok')
    cccc = yield 1
    print(cccc)
    sss = yield 2
    print(sss)

    b = bar()
    b.send(None) #相当于next(b) 第一次send前如果没有next,只能传一个send(None)
    b.send('333')


    
    
    # 生成器都是迭代器,迭代器不一定是生成器
    # list,tuple,dict,string,iterable都是可迭代對象
    # 必須滿足2個條件:1.iter方法 2.next方法
    # 集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
    # 可以使用isinstance()判断一个对象是否是Iterable对象
    # Iterable 迭代對象
    # Iterator 迭代器

    from collections import Iterator, Iterable

    l = [1,2,3,4]
    d = iter(l)
    print(d)
    print(isinstance(l, list))
    print(isinstance(l, Iterable))
    print(isinstance(l, Iterator))
    print(isinstance(d, Iterator))







    无论你选择做什么,追求完美的程度决定你成就的高度。
  • 相关阅读:
    AsyncTask,MailTask,ScheduledTask
    Mysql的事务理解
    MySQL初识
    HTTP 的原理零散知识点
    SpringBoot简单搭建开发
    Android 的生命周期
    C51 虚拟元器件
    JavaSE 知识整合 (更新中……)
    java关键字篇
    Android开启网络权限
  • 原文地址:https://www.cnblogs.com/chiyhua/p/12551130.html
Copyright © 2011-2022 走看看