Day 7- 装饰器

1.本质:装饰器的本质就是函数,为其他函数添加附加功能

  原则:

    1.不修改被修饰函数的源代码

    2.不修改被修饰函数的调用方式

装饰器=高阶函数+函数嵌套(函数的内部又定义了一个函数)+闭包(将变量封存到一个包内,既变量加函数(函数即变量))

高阶函数的定义:

  1.函数接收的参数是一个函数名

  2.函数的返回值是一个函数名

  3.满足上述条件任意一个,都可称之为高阶函数

import time
def foo():
    time.sleep(2)
    print('你好')
def test(func):
    start_time = time.time()
    func()
    stop_time = time.time()
    print('运行时间为%s' % (stop_time-start_time))
test(foo)

 函数嵌套:

def father(x):
    print('baba',x)
    def son():
        print('erzi')
        def grandson():
            print('sunzi')
        grandson()
    son()
    print(locals())
father('a')

 

此时输出值为:

baba a
erzi
sunzi
{'x': 'a', 'son': <function father.<locals>.son at 0x0000029794AF21F0>}

!!!注意函数的作用域!!!先找最近的变量

装饰器实现:

原先的代码:
import
time def timmer(func): def wrapper(): start_time = time.time() func() stop_time = time.time() print('运行时间是%s' %(stop_time-start_time)) return wrapper def test(): time.sleep(0.1) print('执行啦') test = timmer(test) #此时传回来的是wrapper的内存地址 test() #这里执行的是warpper

修改后:
import time
def timmer(func):
    def wrapper():
        start_time = time.time()
        res = func()
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
     return res return wrapper
@timmer #于 test = timmer(test)
def test(): time.sleep(0.1) print('执行啦') a = test() #此处先执行timmer(test),得到wrapper的内存地址, 然后执行wrapper,wrapper里func()执行了下方的test(),然后得到一个返回值,拿res接收,再返回给了wrapper
print(a) #此时就得到了test()的返回值“这是test的返回值”

 

装饰器加上参数: 用*args,**kwargs来接收多个变量

import time
def timmer(func):
    def wrapper(*args,**kwargs): # *args以元组的形式接收,**kwargs接收字典
        start_time = time.time()
        res = func(*args,**kwargs) #执行test(),然后将test()里的返回值接收
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
        return res
    return wrapper
@timmer #相当于 test = timmer(test)
def test(name,age):
    time.sleep(0.1)
    print('执行啦,%s,%s'%(name,age))
    return '这是test的返回值'
test('chris',18)

此时输出值为:

  执行啦,chris,18
  运行时间是0.10074973106384277

 解压序列与值的交换

l = [1,2,5,76,86,34,64]
a,b,*_,d = l
print(a,b,d)
f1 = 4
f2 = 7
f1,f2 = f2,f1
print(f1,f2)

此时输出值为:

1 2 64
7 4

!!!*_表示中间的所有值

 京东主页认证功能:

user_list = [
    {'name':'alex','passwd':'123'},
    {'name':'joe','passwd':'123'},
    {'name':'chris','passwd':'123'},
    {'name':'john','passwd':'123'},
]
current_user = {'username':None,'login':False}
def auth(auth_type = 'filedb'):
    def auth_func(func):
        def wrapper(*args,**kwargs):
            print('认证类型为',auth_type)
            if auth_type == 'filedb':
                if current_user['username'] and current_user['login']:
                    res = func(*args, **kwargs)
                    print(res)
                    return res
                num = input('请输入账号:').strip()
                passwd = input('请输入密码:').strip()
                for i in user_list:
                    if num == i['name'] and passwd == i['passwd']:
                        current_user['username'] = num
                        current_user['login'] = True
                        res = func(*args,**kwargs)
                        return res
                else:
                    print('账号或密码错误')
            elif auth_type == 'ldap':
                print('玩不来')
            else:
                print('啥类型,不知道')
        return wrapper
    return auth_func
@auth(auth_type = 'filedb') #直接执行了auth()函数,然后返回的值就是auth_func ---> 相当于@auth_func
def index():
    print('你好产品经理')
    return '帅得很'
@auth(auth_type = 'asd') def home(): print('欢迎回家') index() home()
posted @ 2020-02-09 10:24  五号世界  阅读(116)  评论(0)    收藏  举报