新闻详情

新闻详情

首页 / 资讯中心 / 详情

Python装饰器自学全解

发布时间:2026/11/13 23:20:58来源:尧图网络
Python装饰器自学全解
1. 关于装饰器这一概念的基本知识, 其中的第一小节内容探讨了这样一个问题, 即究竟什么是装饰器?装饰器属于一种设计模式, 这种设计模式允许在不修改原始函数代码的前提情况下, 往函数内部添加全新的功能内容, 它属于语法糖的一种范畴, 是基于闭包机制以及高阶函数来实现相关效果的。1.第2点, 装饰器究竟是什么东西。从本质上来讲, 这个可调用对象就是装饰器。它的主要功能是接收一个函数当作参数。然后它会返回一个新的函数给你。def decorator(func):def wrapper(*args, **kwargs):# 添加新功能result func(*args, **kwargs)# 添加新功能return resultreturn wrapper2. 关于装饰器的基础知识这一部分, 我们来到了第二小节, 也就是编号为2.1的函数基础知识回顾环节。# 1. 函数是一等公民可以赋值给变量def greet(name):return fHello, {name}!say_hello greet # 函数赋值给变量print(say_hello(Alice)) # Hello, Alice!# 2. 函数可以作为参数传递def apply_function(func, value):return func(value)def square(x):return x * xprint(apply_function(square, 5)) # 25# 3. 函数可以嵌套定义def outer():def inner():return Inner functionreturn inner()# 4. 闭包函数可以记住它被创建时的环境def make_multiplier(n):def multiplier(x):return x * nreturn multipliertimes_3 make_multiplier(3)print(times_3(4)) # 123. 针对基础级别的装饰器这一块内容, 我们展开详细讲解。# 最简单的装饰器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 wrappermy_decoratordef say_hello():print(Hello!)say_hello()# 输出# Something is happening before the function is called.# Hello!# Something is happening after the function is called.3.这是关于第二个部分的内容, 主要是讲解那些带有参数的函数装饰器。def timer_decorator(func):import timedef wrapper(*args, **kwargs):start_time time.time()result func(*args, **kwargs)end_time time.time()print(f{func.__name__} executed in {end_time - start_time:.4f} seconds)return resultreturn wrappertimer_decoratordef slow_function(seconds):time.sleep(seconds)return fSlept for {seconds} secondsprint(slow_function(2))# 输出# slow_function executed in 2.0023 seconds# Slept for 2 seconds3.3 带参数的装饰器def repeat(num_times):装饰器工厂函数返回一个装饰器def decorator_repeat(func):def wrapper(*args, **kwargs):for _ in range(num_times):result func(*args, **kwargs)return resultreturn wrapperreturn decorator_repeatrepeat(num_times3)def greet(name):print(fHello, {name}!)greet(Alice)# 输出# Hello, Alice!# Hello, Alice!# Hello, Alice!3.4 保留函数元信息from functools import wrapsdef preserve_metadata_decorator(func):wraps(func) # 使用wraps保留原函数的元信息def wrapper(*args, **kwargs):包装函数的文档print(fCalling {func.__name__})return func(*args, **kwargs)return wrapperpreserve_metadata_decoratordef calculate_sum(a, b):计算两个数的和return a bprint(calculate_sum.__name__) # calculate_sum如果不使用wraps会是wrapperprint(calculate_sum.__doc__) # 计算两个数的和print(calculate_sum(3, 4)) # 74. 所谓类装饰器这一章节的内容, 其主题是讨论4.1部分, 也就是要把一个类当作装饰器来使用的情景。class TimerDecorator:def __init__(self, func):self.func funcdef __call__(self, *args, **kwargs):import timestart_time time.time()result self.func(*args, **kwargs)end_time time.time()print(fExecution time: {end_time - start_time:.4f} seconds)return resultTimerDecoratordef long_running_operation():time.sleep(1)return Operation completedprint(long_running_operation())4.2 带参数的类装饰器class RetryDecorator:def __init__(self, max_retries3):self.max_retries max_retriesdef __call__(self, func):def wrapper(*args, **kwargs):for attempt in range(self.max_retries):try:return func(*args, **kwargs)except Exception as e:if attempt self.max_retries - 1:raiseprint(fAttempt {attempt 1} failed: {e}. Retrying...)return Nonereturn wrapperRetryDecorator(max_retries3)def unstable_function():import randomif random.random() 0.7:raise ValueError(Random failure!)return Success!print(unstable_function())5. 关于另外的一些装饰器的应用, 在章节的第五点第一个小标题部分, 提到了存在多个装饰器这样的状况。def decorator1(func):wraps(func)def wrapper(*args, **kwargs):print(Decorator 1: Before)result func(*args, **kwargs)print(Decorator 1: After)return resultreturn wrapperdef decorator2(func):wraps(func)def wrapper(*args, **kwargs):print(Decorator 2: Before)result func(*args, **kwargs)print(Decorator 2: After)return resultreturn wrapperdecorator1decorator2def say_hello():print(Hello!)say_hello()# 输出# Decorator 1: Before# Decorator 2: Before# Hello!# Decorator 2: After# Decorator 1: After# 注意装饰器从下往上执行5.第2部分要讲的是装饰器以及与类方法相关的这些内容。def method_decorator(func):wraps(func)def wrapper(self, *args, **kwargs):print(fCalling method {func.__name__} on {self})return func(self, *args, **kwargs)return wrapperclass Calculator:def __init__(self, value0):self.value valuemethod_decoratordef add(self, x):self.value xreturn self.valuemethod_decoratordef multiply(self, x):self.value * xreturn self.valuecalc Calculator(10)print(calc.add(5)) # 15print(calc.multiply(2)) # 306. 关于装饰器的应用示例第6点1, 也就是缓存这个装饰器。from functools import lru_cache# 使用内置的lru_cache装饰器lru_cache(maxsize128)def fibonacci(n):if n 2:return nreturn fibonacci(n-1) fibonacci(n-2)# 自定义缓存装饰器def memoize(func):cache {}wraps(func)def wrapper(*args, **kwargs):key str(args) str(kwargs)if key not in cache:cache[key] func(*args, **kwargs)return cache[key]return wrappermemoizedef expensive_computation(x):print(fComputing for {x}...)import timetime.sleep(1)return x * xprint(expensive_computation(5)) # 会打印Computing for 5...print(expensive_computation(5)) # 直接从缓存返回不会打印6.这是一个用于权限验证装饰器的条目。def require_permission(permission):def decorator(func):wraps(func)def wrapper(user, *args, **kwargs):if permission not in user.get(permissions, []):raise PermissionError(fUser lacks {permission} permission)return func(user, *args, **kwargs)return wrapperreturn decoratorclass UserManager:require_permission(admin)def delete_user(self, user, target_user):return fUser {target_user} deleted by {user[name]}require_permission(editor)def edit_content(self, user, content):return fContent edited by {user[name]}admin_user {name: Alice, permissions: [admin, editor]}editor_user {name: Bob, permissions: [editor]}regular_user {name: Charlie, permissions: []}manager UserManager()print(manager.delete_user(admin_user, old_user)) # 正常执行# print(manager.delete_user(editor_user, old_user)) # 抛出PermissionError6.这第3项是关于日志装饰器的一个内容说明。import loggingfrom datetime import datetimelogging.basicConfig(levellogging.INFO)def log_decorator(func):wraps(func)def wrapper(*args, **kwargs):start_time datetime.now()logging.info(fStarting {func.__name__} at {start_time})try:result func(*args, **kwargs)end_time datetime.now()duration (end_time - start_time).total_seconds()logging.info(fFinished {func.__name__} in {duration:.2f}s)return resultexcept Exception as e:logging.error(fError in {func.__name__}: {e})raisereturn wrapperlog_decoratordef process_data(data):import timetime.sleep(0.5)return [x * 2 for x in data]print(process_data([1, 2, 3, 4, 5]))6.第4部分是关于类型检查装饰器的内容。def type_check(**types):def decorator(func):wraps(func)def wrapper(*args, **kwargs):# 检查位置参数for i, (arg, (param_name, expected_type)) in enumerate(zip(args, types.items())):if not isinstance(arg, expected_type):raise TypeError(fArgument {param_name} must be {expected_type}, fgot {type(arg)})# 检查关键字参数for param_name, value in kwargs.items():if param_name in types and not isinstance(value, types[param_name]):raise TypeError(fArgument {param_name} must be {types[param_name]}, fgot {type(value)})return func(*args, **kwargs)return wrapperreturn decoratortype_check(xint, yint)def add_numbers(x, y):return x yprint(add_numbers(5, 3)) # 8# print(add_numbers(5, 3)) # 抛出TypeError7. 关于装饰器的调试工作以及测试环节, 其中需要着重关注的是第7.1小节所涉及的如何对装饰器进行调试这一具体问题的展开说明。def debug_decorator(func):wraps(func)def wrapper(*args, **kwargs):print(f[DEBUG] Calling {func.__name__})print(f[DEBUG] Args: {args})print(f[DEBUG] Kwargs: {kwargs})result func(*args, **kwargs)print(f[DEBUG] {func.__name__} returned: {result})return resultreturn wrapperdebug_decoratordef divide(a, b):return a / bdivide(10, 2)7.2 测试装饰器import unittestdef validate_input(min_value0, max_value100):def decorator(func):wraps(func)def wrapper(value):if not (min_value value max_value):raise ValueError(fValue must be between {min_value} and {max_value})return func(value)return wrapperreturn decoratorvalidate_input(min_value0, max_value100)def process_score(score):return Pass if score 60 else Failclass TestDecorator(unittest.TestCase):def test_valid_score(self):self.assertEqual(process_score(75), Pass)self.assertEqual(process_score(45), Fail)def test_invalid_score(self):with self.assertRaises(ValueError):process_score(150)with self.assertRaises(ValueError):process_score(-10)if __name__ __main__:unittest.main()8. 要避免出现, 在循环里面去定义装饰器的这样的操作行为。# 陷阱在循环中定义装饰器def create_decorators():decorators []for i in range(3):def my_decorator(func):def wrapper():print(fDecorator {i})return func()return wrapperdecorators.append(my_decorator)return decorators # 所有装饰器都会打印Decorator 2# 正确做法使用闭包捕获变量def create_decorator_fixed(n):def my_decorator(func):def wrapper():print(fDecorator {n})return func()return wrapperreturn my_decorator9. 总结装饰器是中强大且灵活的特性它允许我们增强函数的功能, 意味着我们可以做到无需修改原始函数代码, 从而实现代码复用将通用功能封装在装饰器里面。这能够保持代码整洁, 把关注点进行分离, 使代码变得更易于维护。它有助于实现面向切面编程, 比如进行日志处理, 或者执行权限验证等等。掌握装饰器需要理解
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/13 0:43:49

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/12 23:59:09

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/13 10:09:00

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/13 13:31:48

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/13 16:11:45

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/13 0:02:27

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉