Python教程:对于初学者,几个易懂的装饰器示例用法

2023-12-21 14:40:52

装饰器是Python中的一个高级功能,它可以用来扩展或修改一个函数或方法的功能,而不需要修改其原始代码。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数对象。

装饰器通常用于添加与函数功能无关的额外功能,如日志记录、性能测试、事务处理、缓存和权限校验等。通过使用装饰器,我们可以将与函数功能无关的代码抽离出来,并继续重用。

使用装饰器可以让我们动态地添加功能到函数或方法中,而不需要修改其原始代码。这种动态添加功能的方式被称为“装饰器”(Decorator),提供一种简洁而优雅的方式来修改、扩展或包装函数,使代码更具可读性和可维护性。

1.写一个简单的装饰器:在这个例子中,我们定义了一个名为count_time的装饰器函数。这个函数接受一个函数作为参数,并返回一个新的函数对象wrapper。在wrapper函数中,记录函数的运行的时间 。
接下来,我们使用装饰器来修饰一个名为my_python的函数。我们通过在函数定义之前加上@count_time来应用装饰器。当调用my_python时,实际上是调用了被装饰器返回的wrapper函数。

import time

def count_time(func):
    def wrapper():
        t1 = time.time()
        func()
        t2 = time.time()
        # 保留5位小数
        print('运行时间为:{:.5} s'.format(t2 - t1))

    return wrapper

# 用语法糖@+函数名,就可以直接调用该函数了
@count_time
def my_python():
    time.sleep(1)
    print('我的Python教程,微信公众号:wdPython')


my_python()

# 我的Python教程,微信公众号:wdPython
# 运行时间为:1.0008 s

2.带有返回值的函数,如何写装饰器:下面代码中执行my_python函数后,有一个常量返回值888888,那么你在wrapper函数里面,也要加进去返回值,这样才能打印出my_python函数的返回值。

import time

def count_time(func):
    def wrapper():
        t1 = time.time()
        result = func()
        t2 = time.time()
        # 保留5位小数
        print('运行时间为:{:.5} s'.format(t2 - t1))
        return result
    return wrapper

# 用语法糖@+函数名,就可以直接调用该函数了
@count_time
def my_python():
    time.sleep(1)
    print('我的Python教程,微信公众号:wdPython')
    return 888888

constant = my_python()
print(constant)

输出内容 :

我的Python教程,微信公众号:wdPython
运行时间为:1.0003 s
88888

**3.函数带参数,如何写装饰器:**首先在my_python函数中,定义一个times参数,表示打印我的Python教程的次数。然后在wrapper函数里面,把*ags参数传进来。ags用于接收一个,可变数量的参数列表,可以一个,可以n个。

import time

def count_time(func):
    def wrapper(*ags):
        t1 = time.time()
        result = func(*ags)
        t2 = time.time()
        # 保留5位小数
        print('运行时间为:{:.5} s'.format(t2 - t1))
        return result
    return wrapper

# 用语法糖@+函数名,就可以直接调用该函数了
@count_time
def my_python(times):
    time.sleep(1)
    print('我的Python教程,微信公众号:wdPython\n'*times)
    return 888888

constant = my_python(3)
print(constant)

输出内容:

我的Python教程,微信公众号:wdPython
我的Python教程,微信公众号:wdPython
我的Python教程,微信公众号:wdPython

运行时间为:1.0007 s
888888

2.装饰器带参数:当我们的被装饰的函数是带参数的,此时要怎么写装饰器呢?…

import time
def my_decorator(name):
    def count_time(func):
        def wrapper(*args, **kwargs):
            t1 = time.time()
            func(*args, **kwargs)
            t2 = time.time()
            print(f'[{name}]执行时间为:', t2 - t1)
        return wrapper
    return count_time

@my_decorator(name='李白')
def libai():
    time.sleep(1)
    print('我是李白')

@my_decorator(name='杜甫')
def dufu():
    time.sleep(1)
    print('我是杜甫')

libai()
dufu()

输出内容:
我是李白
[李白]执行时间为:1.0057024955749512
我是杜甫
[杜甫]执行时间为: 1.002488374710083

4.类装饰器的用法:在装饰器内部,我们定义了__init__和__call__方法,它们分别在创建类实例和调用类实例时被调用。

import time

class my_decorator:
    def __init__(self, func):
        self.func = func
        print("执行类的__init__方法")

    def __call__(self, *args, **kwargs):
        # 添加装饰器的功能
        print('进入__call__函数')
        t1 = time.time()
        self.func(*args, **kwargs)
        t2 = time.time()
        print('运行时间为:{:.5} s'.format(t2 - t1))

@my_decorator
def my_python():
    print('我的Python教程,微信公众号:wdPython')
    time.sleep(1.02)

my_python()

输出内容

执行类的__init__方法
进入__call__函数
我的Python教程,微信公众号:wdPython
运行时间为:1.0219 s

5.类装饰器的传参

class my_decorator:
    def __init__(self, arg1, arg2):  # init()方法里面的参数都是装饰器的参数
        print('执行类Decorator的__init__()方法')
        self.arg1 = arg1
        self.arg2 = arg2

    def __call__(self, func):  # 因为装饰器带了参数,所以接收传入函数变量的位置是这里
        print('执行类Decorator的__call__()方法')

        def baiyu_warp(*args):  # 这里装饰器的函数名字可以随便命名,只要跟return的函数名相同即可
            print('执行wrap()')
            print('装饰器参数:', self.arg1, self.arg2)
            print('执行' + func.__name__ + '()')
            func(*args)
            print(func.__name__ + '()执行完毕')

        return baiyu_warp

@my_decorator('李白', '杜甫')
def demo(a, b, c):
    print('函数的参数:', a, b, c)

demo(10, 20, 30)

输出内容:
执行类Decorator的__init__()方法
执行类Decorator的__call__()方法
执行wrap()
装饰器参数: 李白 杜甫
执行demo()
函数的参数: 10 20 30
demo()执行完毕

完毕!!感谢您的收看

----------★★历史博文集合★★----------
我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字典数据可视化 matplotlib 词云图 Pyecharts 海龟画图 Pandas Bug处理 电脑小知识office自动化办公 编程工具
在这里插入图片描述

文章来源:https://blog.csdn.net/gxz888/article/details/135128476
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。