Python 装饰器案例
下面这段代码可以直接复制到一个 .py 文件中运行,覆盖普通装饰器、计时装饰器、带参数装饰器、权限检查和内置装饰器。
from functools import wraps
from time import perf_counter, sleep
def trace(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"call {func.__name__}")
return func(*args, **kwargs)
return wrapper
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = perf_counter()
result = func(*args, **kwargs)
end = perf_counter()
print(f"{func.__name__} cost {end - start:.6f}s")
return result
return wrapper
def repeat(times):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
def require_role(role):
def decorator(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if user.get("role") != role:
raise PermissionError("permission denied")
return func(user, *args, **kwargs)
return wrapper
return decorator
@trace
def add(a, b):
return a + b
@timer
def slow_task():
sleep(0.01)
return "done"
@repeat(3)
def say_hi(name):
print(f"hi {name}")
@require_role("admin")
def delete_post(user, post_id):
return f"user {user['name']} deleted post {post_id}"
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
@property
def passed(self):
return self.score >= 60
@classmethod
def from_dict(cls, data):
return cls(data["name"], data["score"])
@staticmethod
def is_valid_score(score):
return 0 <= score <= 100
def main():
print(add(1, 2))
print(slow_task())
say_hi("Tom")
admin = {"name": "Lucy", "role": "admin"}
print(delete_post(admin, 1001))
student = Student.from_dict({"name": "Jack", "score": 72})
print(student.name, student.passed)
print(Student.is_valid_score(101))
if __name__ == "__main__":
main()