python装饰器

装饰器本质上也是一个函数,装饰器函数用来修饰其他函数,在不改变原函数代码的情况下为函数增加功能而无需修改调用方式

不带参函数的装饰

 1 import time
 2 def show_time(func):# 装饰器函数调用原功能函数并返回一个新的函数对象
 3     def inner():
 4         start = time.time()
 5         func()
 6         end = time.time()
 7         print('函数执行时间为;%s' % (end - start))
 8     return inner
 9 
10 @show_time# 这一步相当于func1 = show_time(func1)
11 def func1():
12     print('func1')
13     time.sleep(1)
14     print('func1 again')
15 func1()# 在这里调用func1实际上是执行了show_time函数里的inner函数

带参函数的装饰

 1 import time
 2 def show_time2(func):# 带参数函数的装饰,修改inner的参数就好了
 3     def inner(values):
 4         start = time.time()
 5         func(values)
 6         end = time.time()
 7         print('函数执行时间为;%s' % (end - start))
 8     return inner
 9 @show_time2
10 def func2(values):
11     print(values)
12     time.sleep(1)
13     print('%s again' % values)
14     print(type(values))
15 func2(123)
16 
17 
18 # *************************假装是分割线*************************
19 def add_show_time(func):# 带参数函数的装饰,修改inner的参数就好了
20     def inner(*args):
21         start = time.time()
22         func(*args)
23         end = time.time()
24         print('函数执行时间为;%s' % (end - start))
25     return inner
26 @add_show_time
27 def add(*args):
28     amount = 0
29     for i in args:
30         amount += i
31     print(amount)
32     time.sleep(1)
33     return amount
34 
35 add(1,2,3,4)

小结

得益于python强大的功能,python的函数可以像普通对象一样存在,可以作为参数传递给另一个函数也可以被重新赋值like

1 def func3():
2     print('1234')
3 func3()
4 print(type(func3))
5 
6 func3 = '1234'
7 print(func3)
8 print(type(func3))

装饰器其实也是一个函数,如果难以理解,可以将其记为一种特定的格式like
装饰器将需要修饰的功能函数作为参数传入==>意味着装饰器需要接受一个参数,我们将需要修饰的函数作为参数传入
装饰器内置一个函数并返回这个内置函数
在内置函数中调用需要修饰的功能函数(这里用到了参数),并增加新功能
@show_time相当于func1 = show_time(func1)

扩展-->带参数的装饰器

 1 def add_show_time(flag):
 2     def show_time(func):
 3         def inner(*args):
 4             start = time.time()
 5             func(*args)
 6             end = time.time()
 7             print('函数执行时间为;%s' % (end - start))
 8             print('这是装饰器传入的参数:%s' % flag)
 9         return inner
10     return show_time
11 @add_show_time('Nathaniel')# 实际上就是将装饰器进行一次封装,再返回装饰器对象
12 # add = add_show_time('Nathaniel')
13 def add(*args):
14     amount = 0
15     for i in args:
16         amount += i
17     print(amount)
18     time.sleep(1)
19     return amount
20 
21 add(1,2,3,4)

 多次装饰

import time

# 编写装饰器,为函数加上统计时间的功能
def show_time(func):
    def inner(*args):
        start_time = time.time()
        func(*args)
        end_time = time.time()
        number = '1998'
        print('add函数执行了%s' %str(end_time - start_time))
    return inner

# 编写装饰器,为函数加上登录功能
def login(func):
    def inner(*args):
        name = input('请输入用户名:')
        password = input('请输入密码:')
        if name == '111' and password == '111':
            func(*args)
        else:print('用户名或密码错误')
    return inner

@login
@show_time
# 随便写个函数
def add(a,b):
    time.sleep(1)
    values = a + b
    print(values)
    return values

add(1,2)

装饰器之登陆

需求:三个页面,进入页面之前需要登录,每个页面登录用的账号都不一样,如果输错账号密码相当于不登录,成功登录一次后再进入其他页面不需要重复登录

userID = {
    '微信账户':('111','111'),
    'QQ账户':('222','222'),
    '支付宝账户':('333','333'),
}

token = False


def login(login_account_type):
    def account_type(func):
        def inner():
            global token
            if not token:
                name = input('请输入你的%s用户名>>: ' % login_account_type).strip()
                password = input('请输入你的%s密码>>: ' % login_account_type).strip()
                if name == userID[login_account_type][0] and password == userID[login_account_type][1]:
                    token = True
                    func()
                else:
                    print('账号或密码错误,默认等于不登录')
                    func()
            else:
                func()
        return inner
    return account_type

@login('微信账户')
def page1(): # 使用微信登录
    print('welcome to the page1')
    while True :# 输入校验,通过break
        choose = input('输入2进入page2,输入3进入page3,输入q退出')
        if choose =='q' or choose == 'Q':
            break
        if choose == '2':
            page2()
            break
        elif choose == '3':
            page3()
            break
        else:
            print('输入错误')
@login('QQ账户')
def page2(): # QQ登录
    print('welcome to the page2')
    while True :# 输入校验,通过break
        choose = input('输入1进入page1,输入3进入page3,输入q退出')
        if choose =='q' or choose == 'Q':
            break
        if choose == '1':
            page1()
            break
        elif choose == '3':
            page3()
            break
        else:
            print('Invalid enter')
@login('支付宝账户')
def page3():
    print('welcome to the page3')
    while True:  # 输入校验,通过break
        choose = input('输入1进入page1,输入2进入page2,输入q退出')
        if choose =='q' or choose == 'Q':
            break
        if choose == '1':
            page1()
            break
        elif choose == '2':
            page2()
            break
        else:
            print('Invalid enter')
page1()
思路

 

posted @ 2017-11-06 16:33  Nathaniel-J  阅读(163)  评论(0编辑  收藏  举报