Raul2018

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

From: https://mp.weixin.qq.com/s/3-1TikeOeLZilHnPzM9I-Q

---------------------------------------------------------------------------------

装饰器是可以为你的函数添加新功能的秘密武器,使你的代码更加优雅和高效。今天我们将探讨可以增强你的函数的 10 个最佳 Python 装饰器。

在 Python 中,函数是一等对象,这意味着你可以将它们分配给变量,将它们作为参数传递,甚至从其他函数返回它们。装饰器是一种强大的方法,可以在不更改源代码的情况下修改或增强函数或方法的行为。这是一个简单的例子来说明装饰器是如何工作的:

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

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

当你运行此代码时,你将看到 my_decorator 函数包装了 say_hello 函数,允许你在调用原始函数之前和之后添加功能。

下面让我们深入了解可以增强 Python 功能的 10 个装饰器。

1、@staticmethod和@classmethod

静态方法和类方法在面向对象编程中至关重要。它们允许你定义可以在类本身而不是类的实例上调用的方法。

class MyClass:
    class_variable = "I am a class variable"
    @staticmethod
    def static_method():
        print("This is a static method")
    @classmethod
    def class_method(cls):
        print(f"This is a class method. Accessing class variable: {cls.class_variable}")
# Usage
MyClass.static_method()
MyClass.class_method()

2、@property

@property 装饰器允许你定义可以像属性一样访问的方法,使你的代码更具可读性并保持封装性。

class Circle:
    def __init__(self, radius):
        self._radius = radius

  @property
    def radius(self):
        return self._radius
    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("Radius cannot be negative")
        self._radius = value
# Usage
circle = Circle(5)
print(circle.radius)
circle.radius = 7

3、@lru_cache

缓存对于优化具有昂贵计算量的函数调用至关重要。

@lru_cache 装饰器缓存函数的结果,节省时间和资源

from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
# Usage
print(fibonacci(50))

4、@timer

对函数进行计时对于性能分析至关重要。

@timer 装饰器可以测量函数的执行时间。

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__} took {end_time - start_time} seconds to execute.")
        return result
    return wrapper
@timer
def slow_function():
    time.sleep(2)
# Usage
slow_function()

5、@log_exception

调试可能是一项具有挑战性的任务。

@log_exception 装饰器可帮助你记录函数内引发的异常,从而简化调试过程。

def log_exception(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            print(f"Exception in {func.__name__}: {e}")
    return wrapper

@log_exception
def divide(a, b):
    return a / b
# Usage
result = divide(10, 0)
小寒聊python
分享算法相关技术文章,欢迎关注
19篇原创内容

 

6、@authenticated

安全性在许多应用中至关重要。

@authenticated 装饰器可用于确保只有授权用户才能访问某些功能

def authenticated(func):
    def wrapper(user, *args, **kwargs):
        if user.is_authenticated:
            return func(user, *args, **kwargs)
        else:
            raise PermissionError("User is not authenticated")
    return wrapper

@authenticated
def access_sensitive_data(user):
    return "Sensitive data here"
# Usage
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
user = User(is_authenticated=True)
print(access_sensitive_data(user))

7、@validate_input

输入验证对于防止意外错误至关重要。

@validate_input 装饰器可以检查和清理函数输入。

def validate_input(*args_types):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for arg, arg_type in zip(args, args_types):
                if not isinstance(arg, arg_type):
                    raise ValueError(f"Invalid argument type for {arg}. Expected {arg_type}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@validate_input(int, str)
def example_function(age, name):
    print(f"Age: {age}, Name: {name}")
# Usage
example_function(25, "John")

8、@retry

在分布式系统和 API 的世界中,重试通常是必要的。

@retry 装饰器可以自动重试一个函数,直到成功。

import random

def retry(max_attempts):
    def decorator(func):
        def wrapper(*args, **kwargs):
            attempts = 0
            while attempts < max_attempts:
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"Attempt {attempts+1} failed with error: {e}")
                    attempts += 1
                    delay = 2 ** attempts + random.uniform(0, 1)
                    time.sleep(delay)
            raise Exception("Max retries reached")
        return wrapper
    return decorator
@retry(max_attempts=3)
def unstable_function():
    if random.random() < 0.7:
        raise ValueError("Something went wrong")
# Usage
unstable_function()

9、@deprecated

当你需要优雅地逐步淘汰旧函数时,

@deprecated 装饰器可以通过在使用已弃用的函数时发出警告来提供帮助。

import warnings

def deprecated(func):
    def wrapper(*args, **kwargs):
        warnings.warn(f"Function {func.__name__} is deprecated.", category=DeprecationWarning)
        return func(*args, **kwargs)
    return wrapper
@deprecated
def old_function():
    return "This is an old function"
# Usage
result = old_function()

10、@memoize

记忆化是一种缓存技术,用于存储昂贵的函数调用的结果以供将来使用。

@memoize 装饰器简化了这个过程。

def memoize(func):
    cache = {}

def wrapper(*args):
        if args in cache:
            return cache[args]
        result = func(*args)
        cache[args] = result
        return result
    return wrapper
@memoize
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
# Usage
print(factorial(10))

这 10 个装饰器可以转换你的 Python 代码,使其更加高效、可读和安全。

posted on 2023-09-20 21:09  Raul2018  阅读(56)  评论(0编辑  收藏  举报