首页 > 编程语言 > 详细

4.5 Python3 进阶 - 闭包 & 装饰器

时间:2021-06-18 14:36:16      阅读:30      评论:0      收藏:0      [点我收藏+]

>>返回主目录

技术分享图片
技术分享图片

源码

# 闭包应用:计数器
def counter():
    numbers = [0]

    def add_one():
        numbers[0] += 1
        print(f‘第{numbers[0]}次调用‘)
    return add_one


count1 = counter()  # 调用外函数
count1()  # 调用count1的闭包函数
count1()
count2 = counter()()  # 直接调用外函数的闭包函数
count1()

技术分享图片

源码

# 闭包函数,同级之间可以互相进行访问,例如:
def out_fun(num1, num2):
    num3 = 10

    def inner_fun_1(num4):
        num5 = 20
        sum_nums = num1 + num2 + num3 + num4 + num5
        print(‘所有数字相加后的结果是:‘, sum_nums)

    def inner_fun_2(num):
        inner_fun_1(num)
    return inner_fun_2


sum_total_1 = out_fun(1, 2)  # 调用out_fun装饰器,返回inner_fun_2赋值给变量sum_total_1
sum_total_2 = out_fun(10, 20)  # 调用out_fun装饰器,返回inner_fun_2赋值给变量sum_total_2
sum_total_1(3)
sum_total_1(4)
sum_total_1(5)
sum_total_2(30)  # sum_total_1和sum_total_2内存地址相互独立
sum_total_2(40)

技术分享图片
技术分享图片
技术分享图片

源码

import time


# 装饰器定义
# 简单装饰器格式,传入func为函数
def decorator_1(func):
    def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        print(f‘原函数执行速度是:{end_time - start_time}‘)
    return wrapper


# 装饰器调用
@decorator_1  # 使用@语法糖,调用装饰器
def func_1():
    print(‘func_1 为原函数‘)
    time.sleep(1)


func_1()
# 使用普通方式调用
# call_func = decorator_1(func_1)
# call_func()

技术分享图片

源码

# 万能装饰器
def decorator_2(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print(f‘原函数执行速度是:{end_time - start_time}‘)
    return wrapper


@decorator_2
def func_2(name, courses, date_time=‘2021-06-09‘):
    courses_str = ‘‘
    for i in courses:
        courses_str = courses_str + i + ‘,‘
    print(f‘我是{name},今天是{date_time},学习了:{courses_str}的课程‘)
    time.sleep(1)


func_2(‘Portos‘, [‘Python‘, ‘函数‘, ‘decorator‘], date_time=‘2021-06-10‘)

技术分享图片
技术分享图片

源码

# 带参数装饰器
def decorator_with_para(*para_list, **para_dict):
    def decorator_3(func):
        def wrapper(*args, **kwargs):
            print(‘传入的para_list可供内部装饰器使用:‘, para_list)
            print(‘传入的para_dict可供内部装饰器使用:‘, para_dict)
            start_time = time.time()
            func(*args, **kwargs)
            end_time = time.time()
            print(f‘原函数执行速度是:{end_time - start_time}‘)
        return wrapper
    return decorator_3


@decorator_with_para(‘可变参数‘, para_dict_data=‘关键字参数‘)
def func_3(name, courses, date_time=‘2021-06-09‘):
    courses_str = ‘‘
    for i in courses:
        courses_str = courses_str + i + ‘,‘
    print(f‘我是{name},今天是{date_time},学习了:{courses_str}的课程‘)
    time.sleep(1)


func_3(‘Portos3‘, [‘Python3‘, ‘函数‘, ‘decorator‘], date_time=‘2021-06-10‘)

技术分享图片

源码

# 复合/多层装饰器调用
# 第一个装饰器
def decorate_4(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print(f‘原函数执行速度是:{end_time - start_time}‘)
    return wrapper


# 第二个装饰器
def decorate_5(func):
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        print(f‘此处调用了装饰器decorate_5‘)
    return wrapper


# 第一个装饰器和第二个装饰器都装饰同一个函数
@decorate_5  # 后装饰的,先调用
@decorate_4  # 先装饰的,后调用
def func_4(name, courses, date_time=‘2021-06-09‘):
    courses_str = ‘‘
    for i in courses:
        courses_str = courses_str + i + ‘,‘
    print(f‘我是{name},今天是{date_time},学习了:{courses_str}的课程‘)
    time.sleep(1)


func_4(‘Portos4‘, [‘Python4‘, ‘函数‘, ‘decorate‘], date_time=‘2021-06-10‘)

技术分享图片

源码

# Author:PortosHan
# Datetime:2021/6/17 21:00
# Project:zbcf_python_lesson_project
# 装饰器调用练习(场景:权限验证)
"""
付款时校验登录权限,练习:
第一步:调用付款函数进行付款;
第二步:校验是否登录;
第三步:没有登录,重新登录后再付款;
第四步:登录成功后,重新调用付款函数进行付款。
"""
import time

is_login = False  # 默认没有登录


# 定义一个登录函数,判断是否登录成功
def login():
    user_name = input(‘请输入用户名:‘)
    pwd = input(‘请输入密码:‘)
    if user_name == ‘portos‘.lower() and pwd == ‘123456‘:
        return True
    else:
        return False


# 定义一个装饰器,判断是否登录
def login_decorator(func):
    def wrapper(*args, **kwargs):
        print(‘------校验登录状态------‘)
        global is_login
        if is_login:
            func(*args, **kwargs)
        else:
            print(‘用户没有登录,不能付款,3s后自动跳转到登录页面!‘)
            time.sleep(3)
            # 登录成功/失败后,重新赋值全局变量的值
            is_login = login()
            # 登录成功后,重新调用当前付款函数
            func(*args, **kwargs)
    return wrapper


# 调用付款函数时,使用装饰器校验是否登录
@login_decorator
def pay(money):
    print(f‘------付款金额:{money}元------‘)
    print(‘付款中‘)
    time.sleep(3)
    print(‘------付款成功!------‘)


pay(1000)
# pay(100)

>>返回主目录

4.5 Python3 进阶 - 闭包 & 装饰器

原文:https://www.cnblogs.com/PortosHan/p/14898999.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!