IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python 装饰器(二)进阶 -> 正文阅读

[Python知识库]Python 装饰器(二)进阶

上一篇介绍过普通函数的装饰器的简单用法,如果被装饰的函数需要传入参数,那装饰器则不能使用。因为装饰器中返回的函数并不能接受参数。

一、带参数的功能函数

def decorator(fun):
    def wrapper():
        print('---start---')
        fun()
        print('----end---')

    return wrapper

@decorator
def fun(a,b):
	print(a+b)
	
fun(1,2)
运行结果:

TypeError: wrapper() takes 0 positional arguments but 2 were given

需要两个参数,则可以指定装饰器函数wrapper接受和原函数一样的参数:

def decorator(fun):
    def wrapper(a,b):
        print('---start---')
        fun(a,b)
        print('----end---')

    return wrapper

@decorator
def fun(a, b):
    print(a + b)

fun(1, 2)
运行结果:

---start---
3
----end---

现有如下函数fun1需要3个参数或者fun2不需要参数,需要用同一个装饰器去装饰,这时可以将装饰器中的参数设为不定长参数:

def decorator(fun):
    def wrapper(*args, **kwargs):
        print('---start---')
        fun(*args,**kwargs)
        print('----end---')

    return wrapper


@decorator
def fun(a, b):
    print(a + b)
    
@decorator
def fun1(a, b, c):
    print(a + b + c)

@decorator
def fun2():
    print("无参数")


运行结果:
fun(1,2)
---start---
3
----end---
————————————————————————————————————————————————————————
fun1(1,2,3)
---start---
7
----end---
————————————————————————————————————————————————————————
fun2()
---start---
无参数
----end---

当被装饰的函数有返回值时,由于在装饰器中的wrapper函数中没有返回fun3的调用结果,如下为None

二、功能函数有返回值

def decorator(fun):
    def wrapper(*args, **kwargs):
        print('---start---')
        fun(*args, **kwargs)
        print('----end---')

    return wrapper

@decorator
def fun3():
    return "我是fun3"


print(fun3())
运行结果:
---start---
----end---
None

这种情况则需要在wrapper中返回原功能函数的调用结果:

// An highlighted block
def decorator(fun):
    def wrapper(*args, **kwargs):
        print('---start---')
        res = fun(*args, **kwargs) # 调用被装饰的函数并返回结果
        print('----end---')
        return res
    return wrapper

@decorator
def fun3():
    return "我是fun3"


print(fun3())
运行结果:
---start---
----end---
我是fun3

三、带参数的装饰器
当原函数需要装饰器来传入参数来进行某些操作时,如下使用前文中的装饰器运行:
参数2会做为fun传入,结果显而易见

def decorator(fun):
    def wrapper(*args, **kwargs):
        print('---start---')
        res = fun(*args, **kwargs)
        print('----end---')
        return res

    return wrapper


@decorator(2)
def fun4(a):
    return a


print(fun4(1))
运行结果:
TypeError: 'int' object is not callable

这时需要在定义一层函数来接收装饰器的参数,并返回装饰器函数,如下:

def decorator(num):  # 接收装饰器的参数

    def wrapper1(fun):  # 接收被装饰的函数

        def wrapper(*args, **kwargs):  # 接收被装饰函数的参数
            print("装饰器传入的参数:", num)
            print('---start---')
            res = fun(*args, **kwargs)
            print('----end---')

            return res

        return wrapper

    return wrapper1 # 返回装饰器函数


@decorator(1)
def fun5(a):
    return a


print(fun5(2))

运行结果:
装饰器传入的参数: 1
---start---
----end---
2

四、多层装饰器
当多个装饰器装饰一个功能函数时,来看下执行结果及顺序

def decorator(fun):
    print("执行decorator")
    def wrapper(*args, **kwargs):
        print('---decorator_start---')
        res = fun(*args, **kwargs)
        print('---decorator_end---') # 6.执行 print('---decorator_end---'),而decorator1还没执行完成,则会回到decorator1
        return res
    return wrapper


def decorator1(fun):
    print("执行decorator1")
    def wrapper(*args, **kwargs):
        print('---decorator1_start---') 
        res = fun(*args, **kwargs) # 4.遇到功能函数则会执行decorator中的wrapper
        print('---decorator1_end---') # 7.执行print('---decorator1_end---')
        return res
    return wrapper


@decorator1 # 2.接收decorator的返回结果wrapper,并执行 print("执行decorator1")
@decorator # 1.先执行离原函数最近的装饰器 print("执行decorator")
def fun():
    print("功能函数") # 5.decorator中的返回结果为功能函数,执行  print("功能函数")

fun() # 3.调用功能函数,执行decorator1中的wrapper

运行结果:

执行decorator 
执行decorator1
---decorator1_start---
---decorator_start---
功能函数
---decorator_end---
---decorator1_end---
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:42:01  更:2021-08-16 11:43:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 10:49:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码