python 装饰器

定义:

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象,实现了软件开发中的一个原则“开放-封闭”原则。

封闭:已实现的功能代码块不应该被修改

开放:对现有功能的扩展开放

 

1. 本来有一个函数为test,我想在这基础上获取test运行的时间,就可以通过装饰器来实现

def test():
    time.sleep(2)
    print("in the test")
    
首先创建一个高阶函数,里面再定义一个函数
def timmer(func):
    def warpper(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        stop_time = time.time()
        print("The func run time is %s" % (stop_time - start_time))
    return warpper

## test = timmer(test) 不会触发函数的执行,只返回函数的函数名warpper
## timmer(test)返回的是warpper的内存地址,如果想要在test函数里面传入参数,可以在warpper函数中定义参数    
test = timmer(test)     ## 这行代码可以简化为在test函数前面@timmer        

## 调用函数warpper(),这样就实现了调用方式不变,还能添加额外的功能
test()

2. 给网站模块加入自认证

说明:首先网站有三个模块index、home、bbs,index模块不需要认证,home模块类型为local的需要加入自认证,bbs模块类型为ldap需要打印内容,因为多了一层模块下面还有各种类型,所以装饰器里面还需加入一层函数。

def auth(auth_type):
    print("auth func: ", auth_type)
    def outer_wrapper(func):
        def warpper(*args, **kwargs):
            print("wrapper func args: ", *args, **kwargs)
            if auth_type == "local":
                username = input("Username: ").strip()
                password = input("Password: ").strip()
                if user == username and passwd == password:
                    print("\033[32;1mUser has passwd authentication\033[0m")
                    res = func(*args, **kwargs)
                    print("--after authentication")
                    return res
                else:
                    exit("\033[31;1mInvalid username or password\033[0m")
            elif auth_type == "ldap":
                print("No need.")
        return warpper
    return outer_wrapper

def index():
    print("Welcome to index page")

@auth(auth_type="local")
def home(name):
    print("%s, welcome to home page" % name)
    return "from home"

@auth(auth_type="ldap")
def bbs():
    print("Welcome to bbs page")

if __name__ == "__main__":
    user, passwd = "wangzai", "111111"
    name = "doubi"
    # index()
    print(home(name))  # 相当于 # outer_wrapper = auth("local")     ## 返回outer_wrapper函数名
                               # home = outer_wrapper(home)        ## 返回wrapper函数名
                               # print(home(name))                 ## 调用warpper函数

 

posted @ 2017-12-30 19:24  wang_zai  阅读(189)  评论(0)    收藏  举报