• python-函数(装饰器)


    装饰器

    装饰器的主要功能:

    在不改变函数调用方式的基础上在函数的前、后添加功能。

    装饰器的固定格式:

    #装饰器的本质 :闭包函数
    #功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能
    def timmer(func):
        def inner(*args,**kwargs):
            '''添加函数调用之前的扩展代码'''
            ret = func(*args,**kwargs)
            '''添加函数调用之后的扩展代码'''
            return ret
        return inner

    语法:在被装饰对象的正上方的单独一行,使用@语法糖可以直接调用函数装饰器

    设计模式

    原则 开放封闭原则

    #对扩展是开放的

    #对修改是封闭的 

    1.对扩展是开放的

        为什么要对扩展开放呢? 

        我们必须允许代码扩展、添加新功能。

    2.对修改是封闭的 

        为什么要对修改封闭呢? 

        我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

    装饰器完美的遵循了这个开放封闭原则。

    import time
    def wrapper(func):  # 装饰
        def inner(*args, **kwargs):
            start = time.time()
            ret = func(*args, **kwargs)
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    @wrapper
    def lll():
        time.sleep(0.1)
        print('hello')
    
    lll()

     

    编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
    login_dic={
    "name":"None",
    "passwd":"None",
     }
    with open('passwd.txt', 'r+', encoding='utf-8') as f1:
        f2 = eval(f1.read())
    def login(func):
        def inner(*args, **kwargs):
            '''判断用户名、密码是否在字典中'''
            if login_dic["name"]==f2["name"] and login_dic["passwd"]==f2["passwd"]:
                ret = func(*args, **kwargs)
                return ret
            else:
                name = input("请输入用户名:")
                passwd = input("请输入密码:")
                if name == f2['name'] and passwd == f2['passwd']:
                    print("登陆成功")
                    login_dic['name'] = name
                    login_dic['passwd'] = passwd
                    ret = func(*args, **kwargs)
                    return ret
                else:
                    print("输入有误,请重新输入")
        return inner
    @login
    def fun():
        print("123")
        print("456")
    fun()
    @login
    def check():
        print("789")

     带参数的装饰器

    def timer(func):
        def inner(a):
            start = time.time()
            func(a)
            print(time.time() - start)
        return inner
    
    @timer
    def func1(a):
        print(a)
    
    func1(1)
    
    装饰器——带参数的装饰器
    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1(a,b):
        print('in func1')
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func1('aaaaaa','bbbbbb')
    print(func2('aaaaaa'))
    
    装饰器——成功hold住所有函数传参
    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re
        return inner
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func2('aaaaaa','bbbbbb')
    print(func2('aaaaaa'))
    
    装饰器——带返回值的装饰器
    def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                if flag:
                    print('''执行函数之前要做的''')
                re = func(*args,**kwargs)
                if flag:
                    print('''执行函数之后要做的''')
                return re
            return inner
        return timer
    
    @outer(False)
    def func():
        print(111)
    
    func()
    
    带参数的装饰器格式
    def wrapper1(func):
        def inner():
            print('wrapper1 ,before func')
            func()
            print('wrapper1 ,after func')
        return inner
    
    def wrapper2(func):
        def inner():
            print('wrapper2 ,before func')
            func()
            print('wrapper2 ,after func')
        return inner
    
    @wrapper2
    @wrapper1
    def f():
        print('in f')
    
    f()
    
    多个装饰器装饰同一个函数

    实例

    #带参数的装饰器 开关
    # F = True
    
    F = False
    def outer(flag):
        def wrapper(func):
            def inner(*args,**kwargs):
                if flag:
                    print('before')
                    ret = func(*args,**kwargs)
                    print('after')
                else:
                    ret = func(*args, **kwargs)
                return ret
            return inner
        return wrapper
    
    @outer(F)  #-->@wrapper  -->hahaha = wrapper(hahaha)  #-->hahaha == inner
    def hahaha():
        print('hahaha')
    
    @outer(F)   #shuangww = outer(shuangww)
    def shuangww():
        print('shuangwaiwai')
    
    shuangww()
    hahaha()
    '''
    1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
    2.编写装饰器,实现缓存网页内容的功能:
    具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),
    就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
    '''
    url_l = []
    from urllib.request import urlopen
    
    def get_cache(func):
        def inner(*args,**kwargs):
            url = args[0]
            filename = str(hash(url))
            if url in url_l:
                f = open(filename,'rb')
                ret = f.read()
            else:
                url_l.append(url)
                ret = func(*args, **kwargs)
                f = open(filename,'wb')
                f.write(ret)
            f.close()
            return ret
        return inner
    
    @get_cache
    def get(url):
        return urlopen(url).read()
    
    print(get('http://www.cnblogs.com/linhaifeng'))
    print(get('http://www.cnblogs.com/linhaifeng'))
    print(get('http://www.cnblogs.com/linhaifeng'))
    print(get('http://www.cnblogs.com/linhaifeng'))
    print(get('http://www.cnblogs.com/linhaifeng'))
  • 相关阅读:
    gsoap、c++。webservice的client。
    2.5给定两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表首部。编写函数对这两个整数求和,并用链表形式返回结果。进阶:假设这些数位是正向存放的。
    c++、webServices、gsoap、tinyxml、iconv
    2.4编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或者等于x的结点之前。
    CMD窗口快捷键
    IE7下position:relative与overflow的问题
    关于ASP.NET下,JQuery+AJAX使用JSON返回对象集合List数据的总结
    找不到可安装的 ISAM(必解决)
    jquery mini ui
    Unity3D
  • 原文地址:https://www.cnblogs.com/zhangningyang/p/7245315.html
Copyright © 2020-2023  润新知