zoukankan      html  css  js  c++  java
  • python 装饰器

    装饰器有什么用?

    当你需要给你多个函数加上同一个功能,例如登陆验证,计算程序运行时间。。。

    装饰器的本质:一个闭包函数

    装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

    开放封闭原则

    1.对扩展是开放的

    任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

    2.对修改是封闭的

    因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

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

    装饰器的主要功能:

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

    做一个验证功能的装饰器:
    status = False
    
    
    def login(func):            # 这里func = change,这里的change是最初的change函数
        def inner():
            username = "xiaoming"
            password = 123
            if status == False:
                _username = input("username:").strip()
                _password = input("password").strip()
                if _username == username and _password ==password:
                    global status
                    status = True
                    print("认证成功")
                else:
                    print("验证失败,用户名或密码错误")
            if status:
                return func()           # 这里调用func就是调用最初定义的change函数
        return inner       # 返回inner
    
    
    @login            # 这里@login 叫语法糖 相当于 change = login(change),执行后 login(change)= inner 即change = inner
    def change():
        print("这是查询功能")
        
    
    ret = change()                       # 这里change()相当于调用inner(),ret接收的是inner函数的返回值即change函数
    print(ret)                           # 这里打印的仍然是“这是查询功能”
    带参数的装饰器,并且给登陆验证加上验证方式:
    status = False
    
    
    def login(mode):                                  # 这里login函数接收的是qq验证方式
        print("使用%s验证方式" % mode )
    
        def outer(func):                              # 这里的func依然是change函数
            def inner(*args, **kwargs):
                username = "alex"
                password = "123"
                global user_status
                if status == False:
                    _username = input("username:").strip()
                    _password = input("password:").strip()
                    if _username == username and _password == password:
                        print("认证成功")
                        user_status = True
                    else:
                        print("认证失败")
                if user_status:
                    func(*args, **kwargs)
            return inner
        return outer
    
    
    @login("qq")       # 这里@login(“qq”)相当于ss = login("qq") = outer  , change = ss(change) = outer(change)= inner
    def change(sy, ac):
        print("这是查询功能", sy, ac)
    
    
    change(123, 456)   # 这里依然是调用inner函数
    多个装饰器装饰一个函数:
    import time
    status = False
    
    
    def login(mode):  # 3.这里login函数接收的是qq验证方式
        print("使用%s验证方式" % mode)
        
        def outer(func):  # 6.这里的func是t_inner函数
            def inner(*args, **kwargs):  # 9.这里开始执行inner
                username = "alex"
                password = "123"
                global user_status
                if status == False:
                    _username = input("username:").strip()
                    _password = input("password:").strip()
                    if _username == username and _password == password:
                        print("认证成功")
                        user_status = True
                    else:
                        print("认证失败")
                if user_status:
                    func(*args, **kwargs)  # 10.到这里相当于执行t_inner函数
            
            return inner  # 7.返回inner给@login(qq)= inner = change
        
        return outer  # 5.然后返回outer
    
    
    def delayed(func):  # 2.第一次就会先执行这里 此时这里的func = 最初定义的change函数
        def t_inner(*args, **kwargs):  # 11.执行t_inner函数
            time.sleep(3)
            return func(*args, **kwargs)  # 12.执行最初定义的change函数
        
        return t_inner  # 3.t_inner作为delayed函数的返回值返回给@delayed = delayeg(change)= t_inner
    
    
    @login("qq")  # 4.使用语法糖实现多个装饰器装饰一个函数是,先把语法糖走完在去调用函数。  走到这里时@login相当于ss = login("qq") = outer  , change = ss(change) = outer(change)= inner,然后向下走
                  # 下面的语法糖走完后,此时@login会变成ss = login(“qq”) = ouder  change = ss(delayed(change)= outer(t_inner)= inner
    @delayed      # 1.这里@delayed相当于change = delayed(change)= t_inner 这里login函数接收的是qq验证方式,这里语法糖走完,开始第一次调用函数,此时前面的语法糖会发生变化
    def change(sy, ac):  # 13.调用change()
        print("这是查询功能", sy, ac)  # 14.输出结果结束函数()
        return "功能成功调用"
    
    
    change(123, 456)  # 8.这里调用change相当于调用inner()
    
    
    
    
    
  • 相关阅读:
    PHP 7安装使用体验,升级PHP要谨慎
    PHP里10个鲜为人知但却非常有用的函数
    解决 PHPExcel 长数字串显示为科学计数
    linux安装jdk1.6
    虚拟机下Redhat9 网络配置问题(转)
    windows下的一些命令
    redis高级应用特征
    乐观锁的概念
    windows配置redis(转)
    redis常用命令
  • 原文地址:https://www.cnblogs.com/zt0903/p/10683691.html
Copyright © 2011-2022 走看看