python函数高级编程概念 - 闭包 & 装饰器

一、闭包

        闭包(Closure)是编程语言中一个重要的概念,尤其在函数式编程语言中。闭包允许一个函数访问其外部作用域中的变量,即使这个函数在外部作用域之外被调用。

闭包的定义

闭包是一个函数,它记住了创建它的外部作用域中的变量。换句话说,闭包可以访问其创建时所在作用域的变量,即使这个作用域的代码已经执行完毕。

        1、外部函数嵌套内部函数

        2、调用外部函数 返回内部函数

        3、内部函数可以调用 外部函数定义的变量 以及 声明的参数

闭包的组成部分

  1. 函数:闭包本身是一个函数。
  2. 外部作用域的变量:闭包可以访问并可能修改这些变量。

闭包的用途

  1. 数据封装:闭包可以用于封装数据和操作这些数据的函数,类似于对象。
  2. 延迟计算:闭包可以延迟执行某些计算,直到实际需要结果时。
  3. 回调函数:在事件驱动编程中,闭包常用于定义回调函数,携带额外的参数。
  4. 柯里化:闭包可以用于实现函数的部分应用或柯里化。
  5. 装饰器:装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数

Python中的闭包示例

def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

closure = outer_function(2)
print(closure(3))  # 输出: 5

  • outer_function 是一个函数,它接受一个参数 x
  • inner_function 是一个嵌套函数,它接受一个参数 y 并返回 x + y
  • outer_function 返回 inner_function
  • 当 outer_function(2) 被调用时,它返回一个闭包 closure,这个闭包记住了 x 的值(即2)。
  • 当调用 closure(3) 时,闭包访问并使用了 x 的值(2),计算并返回结果5。

二、装饰器

        定义

        装饰器(decorators)是 Python 中的一种高级功能,它允许你动态地修改函数或类的行为,本质是一个闭包函数。它允许程序员在不修改原始函数代码的情况下给函数添加新的功能。

        基本语法


def my_decorator(func):
    def wrapper(*args, **kwargs):
        # 在调用原始函数之前可以做一些事情
        print("Something before the function is called.")
        
        # 调用原始函数
        result = func(*args, **kwargs)
        
        # 在调用原始函数之后可以做一些事情
        print("Something after the function is called.")
        
        return result
    return wrapper

       

        使用装饰器


        使用装饰器非常简单,只需要在函数定义之前使用 @ 符号加上装饰器的名称即可:

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

         当调用 say_hello() 函数时,实际上是调用了 my_decorator(say_hello) 返回的 wrapper 函数。


       

        参数装饰器


         如果被装饰的函数需要参数,装饰器也需要相应地处理这些参数:

def my_decorator_with_params(func):
    def wrapper(x, y):
        print(f"The numbers are: {x} and {y}")
        result = func(x, y)
        return result
    return wrapper

@my_decorator_with_params
def add(x, y):
    return x + y

print(add(5, 3))  

# 输出: The numbers are: 5 and 3
#       8

     

         带参数的装饰器


        装饰器本身也可以有参数,这种情况下需要定义一个外层函数,它接收装饰器的参数,并返回一个装饰器:

def decorator_with_args(arg):
    def actual_decorator(func):
        def wrapper(*args, **kwargs):
            print(f"Decorator argument: {arg}")
            return func(*args, **kwargs)
        return wrapper
    return actual_decorator

@decorator_with_args("test")
def func():
    print("Function is called.")

func()


         装饰器案例


# 解决带参函数 装饰器 以排序耗时为例
import copy
import random
import time

# 推导式生成一个含有 1000 个数字的列表
data = [random.randint(1, 1000) for i in range(1000)]

# 深层拷贝
data_copy = copy.deepcopy(data)

# time.time()获取当前 时间戳 函数前后 各写一个 两者差值既是程序运行时间
def time_cost(f):
    def calc(tf):
        start = time.time()
        f(tf)
        print(f"{f.__name__} 时间消耗 {time.time() - start}")

    return calc


# sort() 列表排序函数 默认 reverse=False 升序  当 reverse=True 时 降序
@time_cost
def sort_data(tf):
    data.sort(reverse=tf)
    print(data)


# sorted() 内置函数 默认 reverse=False 升序  当 reverse=True 时 降序 返回一个新列表

@time_cost
def sort_data_copy(tf):
    new_data = sorted(data_copy, reverse=tf)
    print(new_data)




sort_data(False)
sort_data_copy(True)

 

结果

 


  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值