Python的装饰器和闭包

引言

Python 的装饰器和闭包是两个强大而灵活的编程概念,它们能让你的代码更简洁、可读性更高,并且可以实现许多高级功能。

什么是闭包

闭包是指在一个内部函数中,引用了外部函数的变量。即使外部函数已经返回,内部函数依然可以访问这些变量。外部函数一般返回内部函数。

闭包示例

def outer(msg):
    message = msg

    def inner():
        print(message)

    return inner

# 创建一个闭包
closure = outer("Hello, World!")
closure()  # 输出: Hello, World!

在这个例子中,inner 是一个闭包,它引用了 outer 的局部变量 message。

闭包的应用

闭包在许多场景下非常有用,比如可以用于创建工厂函数或者封装逻辑

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count

    return counter

counter = make_counter()
print(counter())  # 输出: 1
print(counter())  # 输出: 2
print(counter())  # 输出: 3

在这个例子中,counter 函数是一个闭包,它封装了 count 变量,并提供了增加 count 值的方法。内部函数counter,引用了外部函数的局部变量count,对于内部函数来说,外部函数的局部变量相当于缓存起来。

什么是装饰器

装饰器是一个函数,它接受另一个函数作为参数,并返回一个新函数。装饰器常用于在不改变原函数代码的情况下,扩展或修改函数的行为。

装饰器示例

def decorator(func):
    def wrapper():
        print("函数执行前")
        func()
        print("函数执行后")
    return wrapper

@decorator
def hello():
    print("Hello!")

hello()

在这个例子中,decorator 是一个装饰器,它在 hello 函数执行前后添加了一些额外的行为。

装饰器的应用

装饰器在实际应用中非常有用,可以用于日志记录、访问控制、性能计数、鉴权等场景,特别是在代码已完成,需要在后续补充一些辅助功能的时候,装饰器可以让我们不用大幅度改动已有代码的原有逻辑。以下是一个记录函数执行时间的装饰器示例:

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间 {end_time - start_time:.4f}s")
        return result
    return wrapper

@timer
def slow():
    time.sleep(2)

slow()  # 输出: slow 执行时间 2.0012s

在这个例子中,timer 装饰器测量 slow 的执行时间并输出

使用带参数的装饰器

有时候我们需要使用创建带参数的装饰器,使用过flask的开发者应该比较清楚,设置函数路由时,需要传入一些参数,比如**@ns.route(‘/test’,endpoint=‘test_end’)**,我们可以通过再嵌套一层函数来实现

带参数的装饰器的示例
def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("Lin")  # 输出: Hello, lin! (共3次)

闭包和装饰器的结合

闭包和装饰器可以结合使用,实现更加复杂的功能。以下是一个计数函数调用次数的装饰器示例:

def counter(func):
    count = 0
    def wrapper(*args, **kwargs):
        nonlocal count
        count += 1
        print(f"{func.__name__} 执行了 {count} 次")
        return func(*args, **kwargs)

    return wrapper

@counter
def hello():
    print("Hello!")

hello()  # 输出: hello 执行了 1 次 
hello()  # 输出: hello 执行了 2 次 

在这个例子中,counter 装饰器使用闭包来记录函数的调用次数。

结论

Python 的装饰器和闭包是非常强大且灵活的工具,能够让你的代码更加简洁和高效。通过理解和应用这些概念,你可以在不修改原始代码的情况下扩展功能,并实现许多高级的编程模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值