python—装饰器

1、装饰器

本质上函数,为其他函数添加附加功能

— 不修改被修饰函数的源代码

— 不修改被修饰函数的源代码调用方式

装饰器 = 高阶函数+函数嵌套+闭包

import time

### 定义装饰器
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print('函数运行时间为:',(stop_time-start_time))
        return res
    return  wrapper

@timmer
def cal(l):
    res = 0
    for i in l:
        res += i
        time.sleep(0.1)
    return res

print(cal(range(5)))

  

2、高阶函数

函数的参数或返回值是函数名(函数名是内存地址)

###  高阶函数(函数参数是函数名),修改函数调用方式
import  time

def foo():
    print('来来来啊俩')

def test(func):
    print(func)
    start_time = time.time()
    func()
    stop_time = time.time()
    print('函数运行时间为:',(stop_time-start_time))

test(foo)  ## 原来的调用方式  foo()

  

###  高阶函数(函数返回值是函数名)
def foo():
    print('from the foo')

def test(func):
    return  func

foo = test(foo)
foo()  

  

import time

def foo():
    print('from the foo')

## 不修改foo源代码和调用方式

def timmer (func):
    start_time = time.time()
    func()
    stop_time = time.time()
    print('函数运行时间为:',(stop_time-start_time))
    return func

foo = timmer(foo)
foo()
### 多运行了一次 foo()

  

3、函数嵌套

函数内定义另一个函数

def first(name):
    print('第一层 %s' %name)
    def second():
        print('第二层')
    print(locals())
    ## 两个局部变量   name和second()   {'name': 'gogo', 'second': <function first.<locals>.second at 0x006A1150>}

first('gogo')

  

def first(name):
    name = 'haha'
    print('第一层 %s' %name)
    def second():
        name = 'kako'
        print('第二层%s' %name)
    second()

first('gogo')
## 第一层 haha
## 第二层kako

  

4、装饰器框架 

## 装饰器框架 : 高阶函数+函数嵌套
import time

def timmer(func):
    def wrapper():
        start_time = time.time()
        func()  ### 执行rest()
        end_time = time.time()
        print('函数运行时间为:',(end_time-start_time))
    return  wrapper

@timmer ## 相当于 test = timmer(test)
def test():
    time.sleep(0.1)
    print('test函数运行完毕')

# test = timmer(test)  ## 返回wrapper的地址
# test()  ## 执行wrappper()

test()
## test函数运行完毕
##函数运行时间为: 0.10100579261779785

  

 补充:

## 交换数值
a=1
b=2
a,b=b,a
print(a,b)

  

5、装饰器例子

# 为函数加上认证功能
# 全局变量模拟session
# 装饰器加参数

user_list = [
    {'username':'Amy','passwd':'123'},
    {'username':'Lisa', 'passwd': '123'},
    {'username':'Lucy', 'passwd': '123'},
    {'username':'Bob', 'passwd': '123'},
    {'username':'Fly', 'passwd': '123'},
]

# 记录当前用户状态
current_dic = {'username':None,'login':False}

def auth(auth_type='filedb'):   ##  装饰器加参数
    def auth_func(func):
        def wrapper(*args,**kwargs):
            if current_dic['username'] and current_dic['login']:
                res = func(*args, **kwargs)
                return res
            username = input('用户名:').strip()
            passwd = input('密码:').strip()
            for user_li in user_list:
                if username == user_li['username'] and passwd == user_li['passwd']:
                    current_dic['username'] = username
                    current_dic['login'] = True
                res = func(*args, **kwargs)
                return res
            else:
                print('用户名或密码错误!')
        return wrapper

@auth(auth_type='filedb')   ## auth_func=auth(auth_type='filedb') ---> @auth_func附加了auth_tupe参数 ---> index = auth_func(index)
def index():
    print('xx欢迎您!!')

@auth(auth_type='filedb')
def home(name):
    print('欢迎回到%s的主页!!' %name)

index()
home('abc')

  

posted @ 2019-01-18 17:20  kuluma  阅读(178)  评论(0编辑  收藏  举报