【从零学习python 】33.装饰器的作用(二)

2024-02-29 17:10:29 浏览数 (2)

再议装饰器
代码语言:javascript复制
# 定义函数:完成包裹数据
def makeBold(fn):
    def wrapped():
        return "<b>"   fn()   "</b>"
    return wrapped

# 定义函数:完成包裹数据
def makeItalic(fn):
    def wrapped():
        return "<i>"   fn()   "</i>"
    return wrapped

@makeBold
def test1():
    return "hello world-1"

@makeItalic
def test2():
    return "hello world-2"

@makeBold
@makeItalic
def test3():
    return "hello world-3"

print(test1())
print(test2())
print(test3())

运行结果:

hello world-1 hello world-2 hello world-3

4. 装饰器(decorator)功能
  • 引入日志
  • 函数执行时间统计
  • 执行函数前预备处理
  • 执行函数后清理功能
  • 权限校验等场景
  • 缓存
5. 装饰器示例
例1:无参数的函数
代码语言:javascript复制
def check_time(action):
    def do_action():
        action()
    return do_action

@check_time
def go_to_bed():
     print('去睡觉')

go_to_bed()

上面代码理解装饰器执行行为可理解成

代码语言:javascript复制
result = check_time(go_to_bed)  # 把go_to_bed 当做参数传入给 check_time函数,再定义一个变量用来保存check_time的运行结果
result()  # check_time 函数的返回值result是一个函数, result()再调用这个函数,让它再调用go_to_bed函数
例2:被装饰的函数有参数
代码语言:javascript复制
def check_time(action):
    def do_action(a,b):
        action(a,b)
    return do_action

@check_time
def go_to_bed(a,b):
     print('{}去{}睡觉'.format(a,b))

go_to_bed("zhangsan","床上")
例3:被装饰的函数有不定长参数
代码语言:javascript复制
def test(cal):
    def do_cal(*args,**kwargs):
        cal(*args,**kwargs)
    return do_cal

@test
def demo(*args):
    sum = 0
    for x in args:
        sum  =x
    print(sum)

demo(1, 2, 3, 4)
例4:装饰器中的return
代码语言:javascript复制
def test(cal):
    def do_cal(*args,**kwargs):
        return cal(*args,**kwargs)  # 需要再这里写return语句,表示调用函数,获取函数的返回值并返回
    return do_cal

@test
def demo(a,b):
    return a   b

print(demo(1, 2))  #3

总结: 一般情况下为了让装饰器更通用,可以有return

例5:装饰器带参数
代码语言:javascript复制
def outer_check(time):
    def check_time(action):
        def do_action():
            if time < 22:
                return action()
            else:
                return '对不起,您不具有该权限'
        return do_action
    return check_time

@outer_check(23)
def play_game():
    return '玩儿游戏'

print(play_game())

提高:使用装饰器实现权限验证

以下代码不要求掌握,如果能看懂最好,如果能自己手动写出来,那就太棒了!

代码语言:javascript复制
def outer_check(base_permission):
    def check_permission(action):
        def do_action(my_permission):
            if my_permission & base_permission:
                return action(my_permission)
            else:
                return '对不起,您不具有该权限'
        return do_action
    return check_permission

READ_PERMISSION = 1
WRITE_PERMISSION = 2
EXECUTE_PERMISSION = 4

@outer_check(base_permission=READ_PERMISSION)
def read(my_permission):
    return '读取数据'

@outer_check(base_permission=WRITE_PERMISSION)
def write(my_permission):
    return '写入数据'

@outer_check(base_permission=EXECUTE_PERMISSION)
def execute(my_permission):
    return '执行程序'

print(read(5))

0 人点赞