zoukankan      html  css  js  c++  java
  • Python之函数的本质、闭包、装饰器

    函数名的本质

    函数名本质上就是函数的内存地址。

    1.可以赋值给其他变量,被引用

    def func():
        print('in func')
    
    f = func
    print(f)

    2.可以被当作容器类型的元素

    def f1():
        print('f1')
    
    
    def f2():
        print('f2')
    
    
    def f3():
        print('f3')
    
    l = [f1,f2,f3]
    d = {'f1':f1,'f2':f2,'f3':f3}
    #调用
    l[0]()
    d['f2']()

    3.可以当作函数的参数和返回值

    def f1():
        print('f1')
    
    def func1(argv):
        argv()
        return argv
    
    f = func1(f1)
    f()
    第一类对象(first-class object)指
    1.可在运行期创建
    2.可用作函数参数或返回值
    3.可存入变量的实体。
    
    #可以当做普通变量用!

     

    闭包

    闭包函数:

    内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数
    #函数内部定义的函数称为内部函数

    def wrapper():
        name='laozhang'
        def inner():
            print(name)
        inner()
        print(inner.__closure__)    #检测是不是闭包  cell 就是b包
    wrapper()

    '''
    输出内容:

    laozhang
    (<cell at 0x0000000002167498: str object at 0x00000000026D6CB0>,)

    '''

    由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!

    我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?

    是不是直接就把这个函数的名字返回就好了?

    这才是闭包函数最常用的用法

    判断闭包函数的方法__closure__

    #输出的__closure__有cell元素 :是闭包函数
    def func():
        name = 'eva'
        def inner():
            print(name)
        print(inner.__closure__)
        return inner
    
    f = func()
    f()
    
    #输出的__closure__为None :不是闭包函数
    name = 'egon'
    def func2():
        def inner():
            print(name)
        print(inner.__closure__)
        return inner
    
    f2 = func2()
    f2()

    闭包嵌套

    def wrapper():
        money = 1000
        def func():
            name = 'eva'
            def inner():
                print(name,money)
            return inner
        return func
    
    f = wrapper()
    i = f()
    i()    

    '''
    eva 1000
    '''

    闭包的用处:

    如果说内存函数是个闭包,python内部有一个机制,遇到闭包,会在内存中开启一个内存空间(不会关闭),不会随着函数的结束而关闭,能够节省创建新内存的时间和使用频率。

    应用:网页爬虫

    from urllib.request import urlopen
    
    def index():
        url = "http://www.xiaohua100.cn/index.html"
        def get():
            return urlopen(url).read()
        return get
    
    xiaohua = index()
    content = xiaohua()
    print(content)

    装饰器

    在不改变原函数的基础上,增加其他功能。(验证登录、测试时间、打印日志)

    1.简单的装饰器

    import time
    def func():
        print('更健康')
    def timmer(f):
        def inner():
            start_time = time.clock()
            time.sleep(0.1)
            f()
            end_time = time.clock()
            print('执行时间为%s'%(end_time - start_time))
        return inner
    func = timmer(func)
    func()

    '''

    更健康
    执行时间为0.0998653700182556


    '''
     

    2.语法糖(简单版本的装饰器):

    将@装饰器的函数名,放在被装饰的函数之前。

    import time
    def timmer(f):
        def inner():
            start_time = time.clock()
            time.sleep(0.1)
            f()
            end_time = time.clock()
            print('执行时间为%s'%(end_time - start_time))
        return inner
    @timmer  #相当于func = timmer(func)
    def func():
        print('更健康')
    func()  #inner()

    '''

    更健康
    执行时间为0.1004682374539092


    '''

    3.带参数的装饰器

    import time
    def timmer(f):
        def inner(*args,**kwargs):
            start_time = time.clock()
            time.sleep(0.1)
            f(*args,**kwargs)
            end_time = time.clock()
            print('执行时间为%s'%(end_time - start_time))
        return inner
    @timmer  #相当于func = timmer(func)
    def func(a):
        print('%s更健康'%a)
    @timmer   #相当于func1 = timmer(func1)
    def func1(a,b):
        print('%s和%s更健康'%(a,b))
    func('老')  #
    func1('老','杀毒软件')

    '''

    老哥更健康
    执行时间为0.10024377977801449
    老哥和杀毒软件更健康
    执行时间为0.09983056346016456


    '''

    4.带返回值的装饰器

    import time
    def timmer(f):
        def inner(*args,**kwargs):
            start_time = time.clock()
            time.sleep(0.1)
            ret = f(*args,**kwargs)   #222
            end_time = time.clock()
            print('执行时间为%s'%(end_time - start_time))
            return ret
        return inner
    @timmer  #相当于func = timmer(func)
    def func(a):   #a:老哥
        return 222
    print(func('老哥'))

    '''

    执行时间为0.0996239553012396
    222


    '''

    5.通用装饰器

    def wrapper(func):
        def inner(*args,**kwargs):
            '''执行函数前的操作'''
            ret = func(*args,**kwargs)
            '''执行函数后的操作'''
            return ret
        return inner
    @wrapper
    def func():
        print(66)

    func()
  • 相关阅读:
    Sql与Asp.Net数据类型对应
    EditPlus 使用技巧集萃
    VB.NET and C# Comparison
    测试后行之CodeSmith模板
    ASP.NET需要改进的地方
    LeetCode: Minimum Path Sum
    LeetCode: Merge k Sorted Lists
    LeetCode: Merge Intervals
    LeetCode: Maximum Subarray
    LeetCode: Median of Two Sorted Arrays
  • 原文地址:https://www.cnblogs.com/strive-man/p/8407022.html
Copyright © 2011-2022 走看看