Python装饰器教学

Python装饰器教学

一、装饰器简介

在Python中,装饰器是一种高级语法特性,允许你修改或增强函数、方法或类的行为,而无需修改其源代码。装饰器本质上是一个接受函数作为参数的函数,并返回一个新的函数对象。

二、装饰器的基本用法

下面是一个简单的装饰器示例:

def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

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

say_hello()

输出:

Before function call
Hello!
After function call

在这个例子中,my_decorator 是一个装饰器函数,它接受一个函数 func 作为参数,并返回一个新的函数 wrapperwrapper 函数在调用原始函数 func 之前和之后分别打印一些内容。

通过使用 @my_decorator 语法,我们可以将装饰器应用到任何函数上,如 say_hello 函数。这实际上是将 say_hello 函数作为参数传递给 my_decorator 函数,并将返回的新函数对象重新赋值给 say_hello

三、带参数的装饰器

如果原始函数需要接受参数,我们可以在 wrapper 函数中添加相应的参数,如下所示:

def my_decorator(func):
    def wrapper(name):
        print(f"Before calling {func.__name__}")
        func(name)
        print(f"After calling {func.__name__}")
    return wrapper

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

greet("Alice")

输出:

Before calling greet
Hello, Alice!
After calling greet

在这个例子中,greet 函数接受一个参数 name,并通过装饰器 my_decorator 增强了其行为。注意,在 wrapper 函数中,我们使用 func.__name__ 来获取原始函数的名称。

四、带参数的装饰器工厂

有时,我们可能希望装饰器本身能够接受参数。这可以通过创建一个返回装饰器的函数来实现,如下所示:

def my_decorator_factory(message):
    def my_decorator(func):
        def wrapper(name):
            print(f"{message} Before calling {func.__name__}")
            func(name)
            print(f"{message} After calling {func.__name__}")
        return wrapper
    return my_decorator

@my_decorator_factory("This is a custom message: ")
def greet(name):
    print(f"Hello, {name}!")

greet("Bob")

输出:

This is a custom message: Before calling greet
Hello, Bob!
This is a custom message: After calling greet

在这个例子中,my_decorator_factory 是一个返回装饰器的函数。它接受一个参数 message,并返回一个装饰器函数 my_decorator。这样,我们就可以通过传递不同的参数来创建具有不同行为的装饰器。

五、装饰器的应用场景

装饰器在Python编程中有许多应用场景,例如:

  1. 日志记录:记录函数调用的时间、参数和返回值等信息。
  2. 权限校验:在函数调用之前检查用户权限。
  3. 缓存实现:缓存函数调用的结果,避免重复计算。
  4. 性能统计:测量函数执行的时间并打印性能报告。
  5. 事务处理:确保数据库操作的原子性、一致性和隔离性。
  6. 测试与调试:在开发过程中添加额外的调试信息或测试逻辑。

六、日志记录示例

日志记录是装饰器的一个非常实用的应用场景。下面是一个使用装饰器来实现日志记录的示例:

import logging
from functools import wraps

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 定义一个日志装饰器
def log_decorator(func):
    @wraps(func)  # 使用 functools.wraps 来保留原始函数的元信息(如函数名、文档字符串等)
    def wrapper(*args, **kwargs):
        # 在函数调用前记录日志
        logging.info(f"Calling function {func.__name__} with args {args} and kwargs {kwargs}")
        
        # 调用原始函数并获取结果
        result = func(*args, **kwargs)
        
        # 在函数调用后记录日志
        logging.info(f"Function {func.__name__} returned {result}")
        
        # 返回函数结果
        return result
    
    return wrapper

# 使用装饰器来增强函数
@log_decorator
def add_numbers(a, b):
    """Adds two numbers and returns the result."""
    return a + b

# 调用增强后的函数
result = add_numbers(5, 3)
print(result)

在这个例子中,我们首先导入了 logging 模块和 functools.wraps 装饰器。logging 模块用于记录日志,而 wraps 装饰器用于保留原始函数的元信息,这样在日志中就可以正确地显示函数名。

我们定义了一个名为 log_decorator 的装饰器,它接受一个函数作为参数,并返回一个新的函数 wrapper。在 wrapper 函数内部,我们在调用原始函数前后分别记录了日志。

然后,我们使用 @log_decorator 语法将装饰器应用到 add_numbers 函数上。这样,每当我们调用 add_numbers 函数时,就会自动记录相应的日志。

运行这段代码,你将看到类似以下的输出:

2023-04-25 10:00:00,000 - INFO - Calling function add_numbers with args (5, 3) and kwargs {}
2023-04-25 10:00:00,001 - INFO - Function add_numbers returned 8
8

这里的日志输出显示了函数调用前后的信息,包括函数名、参数和返回值。这对于调试和监控程序的运行非常有用。

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介:零基础小白快速学程序员大爱语言――Python,易学易用易就业!!!目标人群: 熟悉电脑基本操作,编程零基础或已具备Python或其它编程语言的人群。课程目标:绝对零基础Python3.x 入门,掌握Python语言常数据类型与操作、语句语法、流程控制、函数定义、模块管理,类与面向对象编程,错误与异常处理,文件读写等知识;为以后Python各方向领域编程打下坚实基础。课程特色: 讲师具有丰富的IT一线技术研发及教学经验,教学深入出,通俗易懂,图例教学杜绝枯燥PPT诵读;课程知识点覆盖面广,循环渐进;案例丰富、取材实战,即学即用!课程目录:01-计算机基础常识.mp402-Python语言概览、安装与运行.mp403-Python 变量、数据类型及存储.mp404-Python 常用数据类型概览.mp405-数值与字符串.mp406-列表list.mp407-字典表dict 与元组 tuple.mp408-文件与类型汇总.mp409-语句、表达式与if分支.mp410-循环语句.mp411-迭代.mp412-函数定义与参数.mp413-函数与Lambda表达式.mp414-函数应用与工具.mp415-包与模块管理及面向对象初步.mp416-面向对象编程OOP 01.mp417-面向对象编程OOP 02.mp418-面向对象编程OOP 03.mp419-异常处理及测试.mp420-unittest单元测试.mp421-数值、日期与时间.mp422-对象持久化.mp423-字符与编码.mp424-正则表达式.mp425-系统编程.mp426-python并行编程.mp427-函数高级应用及装饰器.mp428-Python-SublimeText-Python-配置.mp429-虚拟环境配置-csv文件读取处理.mp430-JSON-Excel 数据文件处理.mp431-Python 操作SQLite.mp4

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值