Python3至装饰器,高阶函数,嵌套函数

装饰器详解与应用
本文深入探讨了Python装饰器的概念及其工作原理,并通过实例演示如何使用装饰器进行函数增强及登录验证等功能。
# Author:Allister.Liu
# !/usr/bin/env python

import time


"""
    装饰器:本质是函数(装饰其它函数),就是为其它函数添加附加功能。
    
    原则:
        1、不能修改被装饰的函数的源代码;
        2、不能修改被装饰的函数的调用方式
        
        
    实现装饰器只是储备:
        1、函数即“变量”;
        2、高阶函数;
            a、把一个函数名当做实参传递给另一个函数(再不修改源代码的同时,为其它函数附加新功能)
            b、返回值中包含函数名(不修改函数的调用方式)
        3、嵌套函数。
        
    高阶函数 + 嵌套函数 ==》 装饰器
"""



# def start():
#     print("in the start...")
#
# def test(func):
#     start_time = time.time()
#     func()
#     stop_time = time.time()
#     print("the func run time is %5f s" % (stop_time - start_time))


# start()
"""
    装饰器举例:test函数中,func(可以是一个函数名《函数名对应的是内存地址》)参数被传入函数start,即 test = func = start,其中func()也就是调用被传入的参数func即start()
    所以,test()调用了start()的同时,也附加了打印执行时间的功能。
"""
# test(start)



"""

def timmer(func):
    def warpper():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("the func run time is %4f 秒" % (stop_time - start_time))
    return warpper


def test01():
    time.sleep(2)
    print("in the test01")

test01 = timmer(test01)
test01()
    第一种:
"""






"""
第二种:

    @timmer : 等于 test01 = timmer(test01)        test01() = timmer()


def timmer(func):
    def warpper():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("the func run time is %4f 秒" % (stop_time - start_time))
    return warpper

@timmer
def test01():
    time.sleep(2)
    print("in the test01")

test01()

"""




"""
 最终版:适用于所有方法,有参数无参数都可以
"""
def timmer(func):
    def warpper(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        stop_time = time.time()
        print("the func run time is %4f 秒" % (stop_time - start_time))
    return warpper

@timmer
def test01():
    time.sleep(2)
    print("in the test01")

test01()

  

# Author:Allister.Liu
# !/usr/bin/env python
# -*- coding:utf-8-*-

"""
需求:使用装饰器实现登录页面的验证
    公司网站:每一个页面当做一个函数,其中主页(index)不需要登录,其余页面都需要登录后才能访问



user, pwd = "Allister", "123456"

# 装饰器实现登录验证
def auth(func):
    def wrapper(*args, **kwargs):
        username = input("UserName:").strip()
        password = input("Password:").strip()

        if username == user and pwd == password:
            print("user logined sucess!")
            return func(*args, **kwargs)
        else:
            exit("Invalid username or password ")
    return wrapper



# 无需登录
def index():
    print("welcome to index page")

# 需登录
@auth
def manage():
    print("welcome to manage page")

# 需登录
@auth
def bbs():
    print("welcome to bbs page")


index()
manage()
bbs()

"""


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


"""
    需求优化:manage使用local验证,bbs使用ldap验证
"""

user, pwd = "Allister", "123456"

# 装饰器实现登录验证
def auth(auth_type):
    def auth_status(func): #manage at 0x000000000413DD08
        def wrapper(*args, **kwargs):
            if auth_type == "local":
                username = input("UserName:").strip()
                password = input("Password:").strip()

                if username == user and pwd == password:
                    print("user logined sucess!")
                    return func(*args, **kwargs)
                else:
                    exit("Invalid username or password ")
            elif auth_type == "ldap":
                print("ldap验证登录...")
        return wrapper
    return auth_status



# 无需登录
def index():
    print("welcome to index page")

# 需登录
@auth(auth_type="local")        # manage = auth(auth_type="local") :auth_status门牌,也就是manage=auth_status(manage), wrapper门牌
def manage():
    print("welcome to manage page")

# 需登录
@auth(auth_type="ldap")
def bbs():
    print("welcome to bbs page")


# index()
manage()
# bbs()

  

# Author:Allister.Liu



def decorator(func):
    print("decorator")
    def wrapper(*args, **kwargs):
        print("wrapper")
        func()
    return wrapper


@decorator
def test():
    print("the test function")


test()

  

转载于:https://www.cnblogs.com/allister/p/8303707.html

<think>好的,用户现在想了解装饰器中的高阶函数,我需要详细解释这个概念。首先,回忆一下之前的对话,用户已经对装饰器有了基本的了解,用快递打包和咖啡加料的例子做了说明。现在用户可能希望深入理解装饰器背后的机制,特别是高阶函数的作用。 首先,我需要明确高阶函数的定义。高阶函数是指接收函数作为参数,或者返回函数函数。在装饰器中,高阶函数是关键,因为装饰器本身就是一个高阶函数,它接收被装饰的函数作为参数,并返回一个新的函数。 接下来,要考虑如何用通俗易懂的例子来解释高阶函数。之前的快递打包和咖啡的例子可能不够,需要新的类比。比如,可以想象厨师做菜,高阶函数就像是给菜品添加额外步骤的工具,比如先洗菜再切菜,最后烹饪,每一步都可能是一个高阶函数处理原始函数(烹饪过程)。 然后,需要分步骤说明高阶函数装饰器中的作用。例如,装饰器的结构通常是一个外层函数接受函数作为参数,内层函数包裹原函数,添加新功能。这里的高阶函数就是外层函数,它返回内层函数,从而实现了对原函数的装饰。 还要注意用户可能存在的疑问点,比如为什么需要返回函数而不是直接执行?这是因为装饰器的作用是修改函数的行为,而不是立即执行它。返回新函数后,当原函数被调用时,才会执行装饰后的逻辑。 另外,需要强调装饰器的执行顺序和嵌套关系。比如多个装饰器叠加时,高阶函数的调用顺序是怎样的,执行顺序又是如何的。这里可能需要用例子说明,比如先用装饰器A,再用装饰器B,实际执行时是B先包裹A,再包裹原函数,但执行顺序是从外到内。 还要考虑用户可能的实际应用场景,比如日志记录、权限验证等,说明高阶函数如何在这些场景中被使用。例如,一个记录日志的高阶函数,可以在函数执行前后打印日志信息,而不需要修改原函数的代码。 最后,确保语言通俗,避免过多专业术语,用生活中的例子帮助理解。比如把高阶函数比作快递打包的不同步骤,每个步骤都是一个处理函数,最终得到一个完全包装好的快递(装饰后的函数)。 总结下来,回答结构需要包括:高阶函数的定义、在装饰器中的作用、具体例子(代码示例)、执行流程分析、常见应用场景以及注意事项。同时,结合之前的快递打包比喻,保持一致性,帮助用户建立连贯的理解。</think>让我们用「厨师做菜」的比喻来理解装饰器中的高阶函数,通过一个完整的代码案例剖析其运作机制: --- ### 🌟 **核心定义** **高阶函数 = 接收函数当食材 / 返回函数当成品 的函数** ```python # 典型的高阶函数结构 def 阶厨师(原食谱): # 接收函数作为参数 def 改良食谱(): # 定义新函数(闭包) ...增强操作... # 添加新功能 return 原食谱() # 调用原函数 return 改良食谱 # 返回新函数 ``` --- ### 🥘 **生活化比喻** 想象你有一个**基础番茄炒蛋食谱**(原函数): 1. **切菜师傅**(高阶函数1):接收食谱,添加「切西红柿」「打鸡蛋」步骤 2. **火候师傅**(高阶函数2):接收改良后的食谱,添加「热油」「控制火候」步骤 3. **摆盘师傅**(高阶函数3):接收再次改良的食谱,添加「撒葱花」「装盘」步骤 **最终成品** = 摆盘师傅(火候师傅(切菜师傅(基础食谱))) --- ### 📜 **代码案例:三阶增强器** ```python # 高阶函数1:处理食材 def 切菜师傅(func): def 切好食材的菜谱(): print("【切菜部】西红柿切片,鸡蛋打散") result = func() # 原食谱的执行位置 print("【切菜部】食材预处理完成") return result return 切好食材的菜谱 # 高阶函数2:控制烹饪 def 火候师傅(func): def 带火候控制的菜谱(): print("🔥 热锅凉油,七成油温") result = func() # 这里可能是已经切好的菜谱 print("🔥 转小火收汁") return result return 带火候控制的菜谱 # 原函数(基础食谱) @火候师傅 # 第三层装饰 @切菜师傅 # 第二层装饰 def 番茄炒蛋(): print("🍳 核心步骤:翻炒西红柿和鸡蛋") return "菜品完成" # 等价于: # 番茄炒蛋 = 火候师傅(切菜师傅(番茄炒蛋)) ``` --- ### 🔍 **执行流程拆解** **当调用番茄炒蛋() 时:** 1. **触发最外层装饰器**(火候师傅) ```python def 带火候控制的菜谱(): print("🔥 热锅凉油,七成油温") result = 切好食材的菜谱() # 进入下一层 print("🔥 转小火收汁") return result ``` 2. **进入中层装饰器**(切菜师傅) ```python def 切好食材的菜谱(): print("【切菜部】西红柿切片,鸡蛋打散") result = 原番茄炒蛋() # 调用核心函数 print("【切菜部】食材预处理完成") return result ``` 3. **执行核心函数** ```python print("🍳 核心步骤:翻炒西红柿和鸡蛋") return "菜品完成" ``` **完整输出:** ```shell 🔥 热锅凉油,七成油温 【切菜部】西红柿切片,鸡蛋打散 🍳 核心步骤:翻炒西红柿和鸡蛋 【切菜部】食材预处理完成 🔥 转小火收汁 ``` --- ### 🧩 **高阶函数三要素** | 要素 | 作用 | 对应代码段 | |---------------------|-------------------------------|-------------------------------| | **函数作为参数** | 接收要增强的目标 | `def 切菜师傅(func):` | | **内部定义新函数** | 创建增强版函数 | `def 切好食材的菜谱():` | | **返回新函数** | 替换原函数实现功能扩展 | `return 切好食材的菜谱` | --- ### 🎯 **高阶函数的进阶用法** **1. 带参数的装饰器** ```python def 调味师(咸度): # 外层函数接收参数 def 装饰器(func): # 中层接收函数 def 调味菜品(*args): # 内层处理参数 print(f"撒{咸度}克盐") return func(*args) return 调味菜品 return 装饰器 @调味师(咸度=5) # 先执行调味师(5),返回真正的装饰器 def 炒青菜(): ... ``` **2. 装饰器叠加顺序实验** ```python def 装饰器A(func): def 包装(): print("A-start") func() print("A-end") return 包装 def 装饰器B(func): def 包装(): print("B-start") func() print("B-end") return 包装 @装饰器A @装饰器B def 测试(): print("CORE") 测试() # 输出: # A-start # B-start # CORE # B-end # A-end ``` --- ### 💡 **为什么需要高阶函数?** - **不改源码增强功能**:像给手机套保护壳,不影响手机本身 - **功能模块化**:每个装饰器专注一个增强点(如日志/权限/性能监测) - **灵活组合**:像乐积木自由搭配(权限校验+日志记录+缓存) --- ### 🛠️ **实际应用场景** 1. **接口鉴权**(验证token后再执行业务逻辑) 2. **执行耗时统计**(记录函数运行时间) 3. **自动重试机制**(网络请求失败时重试3次) 4. **结果缓存**(记住函数计算结果,避免重复执行) 5. **调试追踪**(打印函数调用栈信息) 下次当你想给函数"安装插件"时,记得高阶函数这个强大的工具!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值