python装饰器

当涉及到带有参数的装饰器时,需要在装饰器内再套一层函数。这样的装饰器可以接受参数,并根据参数的不同采取不同的行为。

以下是一个带有参数的装饰器的示例:

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

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

# 调用被装饰后的函数
greet("Alice")

在这个例子中,repeat 是一个带有参数的装饰器。它返回一个装饰器函数 decorator,这个函数接受被装饰的函数 func 作为参数,并返回一个新的函数 wrapper。这个新的函数在调用原始函数前后重复执行了 n 次。

整个过程可以总结为:

  1. 定义带参数的装饰器: 定义一个高阶函数(repeat),它接受装饰器参数,并返回真正的装饰器函数(decorator)。

  2. 定义包装函数: 在装饰器函数内部定义一个新的函数(wrapper),这个函数负责在调用原始函数前后执行额外的代码。

  3. 返回包装函数: 装饰器函数返回包装函数,替换了原始函数。

  4. 使用带参数的装饰器: 使用 @decorator_name(argument) 语法将装饰器应用于函数,或者手动调用 decorator_name(argument)(func)

带参数的装饰器使得我们可以更灵活地定制装饰器的行为。这在处理不同函数或场景时尤其有用。

使用场景:

装饰器在许多场景中都非常有用,它们提供了一种灵活的方式来修改或扩展函数的行为。以下是一些常见的使用场景:

  • 日志记录: 记录函数的输入、输出或运行时间,以便进行调试或性能分析。

def log_function_call(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} called with args: {args}, kwargs: {kwargs}. Result: {result}")
        return result
    return wrapper

@log_function_call
def add(a, b):
    return a + b
  • 性能分析: 测量函数的执行时间,帮助找到代码中的性能瓶颈。 
import time

def measure_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Function {func.__name__} took {end_time - start_time} seconds to run.")
        return result
    return wrapper

@measure_time
def heavy_computation():
    # Some computationally intensive task
    pass
  • 权限验证: 检查用户权限或角色,并根据情况允许或拒绝访问某个函数或资源。
def require_admin(func):
    def wrapper(*args, **kwargs):
        if is_admin():
            return func(*args, **kwargs)
        else:
            raise PermissionError("Admin access required.")
    return wrapper

@require_admin
def delete_user(user_id):
    # Delete user logic
    pass
  • 缓存: 缓存函数的输出,避免重复计算。 
def memoize(func):
    cache = {}

    def wrapper(*args, **kwargs):
        key = (args, frozenset(kwargs.items()))
        if key not in cache:
            cache[key] = func(*args, **kwargs)
        return cache[key]

    return wrapper

@memoize
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)
  •  事务管理: 在函数执行前后进行事务的开启和提交,或者在出现异常时进行回滚。
def transactional(func):
    def wrapper(*args, **kwargs):
        start_transaction()
        try:
            result = func(*args, **kwargs)
            commit_transaction()
            return result
        except Exception as e:
            rollback_transaction()
            raise e

    return wrapper

@transactional
def transfer_funds(sender, recipient, amount):
    # Transfer funds logic
    pass
  • 重试机制: 在函数执行失败时,自动重试,增强系统的鲁棒性。
import time

def retry_on_error(max_retries=3, delay=1):
    def decorator(func):
        def wrapper(*args, **kwargs):
            retries = 0
            while retries < max_retries:
                try:
                    result = func(*args, **kwargs)
                    return result
                except Exception as e:
                    print(f"Error: {e}. Retrying...")
                    time.sleep(delay)
                    retries += 1
            raise RuntimeError(f"Failed after {max_retries} retries.")

        return wrapper

    return decorator

@retry_on_error()
def potentially_failing_function():
    # Some code that might fail
    pass
  • 输入验证: 检查函数输入参数的有效性,确保满足预期条件。 
def validate_inputs(*types):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for arg, arg_type in zip(args, types):
                if not isinstance(arg, arg_type):
                    raise TypeError(f"Expected {arg_type}, but got {type(arg)} for argument {arg}.")
            return func(*args, **kwargs)

        return wrapper

    return decorator

@validate_inputs(str, int)
def example_function(name, age):
    # Function logic
    pass
  •  单例模式: 确保类只有一个实例,通过装饰器来实现单例模式。
def singleton(cls):
    instances = {}

    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return wrapper

@singleton
class MyClass:
    pass
  •  参数化装饰器: 装饰器也可以接受参数,使其更加灵活和通用。
def repeat(n=2):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello, {name}!")
  •  动态注册插件: 使用装饰器来动态注册插件,实现插件式架构。
plugins = []

def register_plugin(func):
    plugins.append(func)
    return func

@register_plugin
def my_plugin():
    # Plugin logic
    pass

# 使用注册的插件
for plugin in plugins:
    plugin()
  • 打印函数执行时间: 使用装饰器记录函数执行时间,用于性能优化。 
import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time:.2f} seconds to run.")
        return result
    return wrapper

@timing_decorator
def long_running_function():
    # Some time-consuming task
    pass
  • 异步装饰器: 适用于异步函数的装饰器,允许在异步代码中添加功能。 
import asyncio

def async_decorator(func):
    async def wrapper(*args, **kwargs):
        print("Before async function")
        result = await func(*args, **kwargs)
        print("After async function")
        return result
    return wrapper

@async_decorator
async def async_example():
    # Async function logic
    pass

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值