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)
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 代码,使其更加高效、可读和安全。