python内置的装饰器最通俗的讲解_如何最简单、通俗地理解Python的装饰器?

目录:

一、笔记

二、我的自学路线

三、笔记目录

一、笔记

1) 装饰器的定义

① 装饰器就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数。

② 装饰器的功能特点:1. 不修改已有函数的源代码

2. 不修改已有函数的调用方式

3. 给已有函数增加额外的功能

③ 闭包和装饰器的区分:如果闭包函数的参数有且只有一个,并且是函数,那么这个闭包函数称之为装饰器。

④ 写代码要遵循开放封闭原则,它规定已经实现的功能代码不允许被修改,但可以被扩展。

2) 装饰器示例代码

# 定义装饰器

def decorator(func):

def inner():

# 在内部函数(inner函数)里实现对已有函数(comment函数)装饰

print('已添加登陆认证')

func()

return inner

def comment():

print('发表评论')

# 调用装饰器对已有函数进行装饰,左边的 comment = inner

comment = decorator(comment)

# 调用方式不变

comment()

运行结果:

已添加登陆认证

发表评论

3) 装饰器的语法糖写法

① 如果有多个函数都需要添加登陆验证的功能,每次都需要编写 func = decorator(func1)、func = decorator(func2)......这样代码对已有函数进行装饰的做法比较麻烦。

② python提供一个装饰函数更加简单的写法,那就是语法糖,语法糖的书写格式为:@装饰器名字,通过语法糖的方式完成对已有函数的装饰。

# 定义装饰器

def decorator(func):

def inner():

# 在内部函数(inner函数)里实现对已有函数(comment函数)装饰

print('已添加登陆认证')

func()

return inner

@decorator # 相当于 comment = decorator(comment)

def comment():

print('发表评论')

# 调用方式不变

comment()

运行结果:

已添加登陆认证

发表评论

4) 装饰器的执行时机

① 当前模块加载完成以后,装饰器会立即执行,对已有函数进行装饰。

# 定义装饰器

def decorator(func):

print('装饰器执行了')

def inner():

# 在内部函数(inner函数)里实现对已有函数(comment函数)装饰

print('已添加登陆认证')

func()

return inner

@decorator # 相当于在函数定义后添加 comment = decorator(comment),即当再调用comment函数时,已经运行了 decorator(comment) 函数

def comment():

print('发表评论')

运行结果:

装饰器执行了

5) 装饰器的使用场景

装饰器使用场景常用于:

① 函数执行时间的统计。

② 输出日志信息。

import time

# 定义装饰器

def decorator(func):

print('装饰器执行了')

def inner():

# 获得已有函数执行时间的统计

begin = time.time()

func()

end = time.time() # end 前的缩进要保持一致

result = end - begin

print(f'函数执行完成耗时:{result}')

return inner

@decorator

def work():

for i in range(30):

print('发表评论')

# 调用方式不变

work()

运行结果:

装饰器执行了

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

发表评论

函数执行完成耗时:0.008002519607543945

6) 通用装饰器的使用

① 通用装饰器:可以装饰任意类型的函数。

② 使用装饰器装饰已有函数的时候,内部函数的类型和要装饰的已有函数的类型保持一致。

# 装饰带有参数的函数

def decorator(func):

print('装饰器执行了')

def inner(num1, num2): # 装饰器内部函数类型 inner(num1, num2),为两个入口参数的函数

print('正在努力执行加法计算')

func(num1, num2)

return inner

@decorator # add_num = decorator(add_num)

def add_num(num1, num2): # 装饰器已有函数类型 add_num(num1, num2),为两个入口参数的函数

result = num1 + num2

print(f'结果为:{result}')

add_num(1,2)

运行结果:

装饰器执行了

正在努力执行加法计算

结果为:3

# 装饰带有参数的函数

def decorator(func):

print('装饰器执行了')

def inner(num1, num2): # 装饰器内部函数类型 inner(num1, num2),为两个入口参数的函数

print('正在努力执行加法计算')

func(num1, num2)

return inner

@decorator # add_num = decorator(add_num)

def add_num(num1, num2): # 装饰器已有函数类型 add_num(num1, num2),为两个入口参数的函数

result = num1 + num2

add_num(1,2)

print(f'结果为:{result}') # 报错,不是返回值时,无法调用函数内变量

运行结果:

装饰器执行了

正在努力执行加法计算

--------------------------------------------------------------------------- NameError Traceback (most recent call last) in 13 14 add_num(1,2) ---> 15 print(f'结果为:{result}') # 报错,不是返回值时,无法调用函数内变量 NameError: name 'result' is not defined

# 装饰带有参数、返回值的函数

def decorator(func):

print('装饰器执行了')

def inner(num1, num2):

print('正在努力执行加法计算')

num = func(num1, num2) # func(num1, num2) 即 add_num(num1, num2) 运行后函数返回值 result 赋值给 num,最后返回 num

return num

return inner

@decorator

def add_num(num1, num2):

result = num1 + num2

return result

print(f'结果为:{add_num(1,2)}') # 报错,有返回值,可以打印返回值

运行结果:

装饰器执行了

正在努力执行加法计算

结果为:3

# 装饰带有不定长参数、返回值的函数

def decorator(func):

print('装饰器执行了')

def inner(*args, **kwargs):

print('正在努力执行加法计算')

num = func(*args, **kwargs)

return num

return inner

@decorator

def add_num(*args, **kwargs):

result = 0

for value in args: # args为一个元组

result += value

for value in kwargs.values(): # kwargs为一个字典

result += value

return result

result = add_num(1,2,a=3)

print(f'结果为:{result}') # 调用的是add_num(1,2,a=3)赋值的变量result,不是函数里的result

运行结果:

装饰器执行了

正在努力执行加法计算

结果为:6

7) 多个装饰器的使用

① 多个装饰器的装饰过程:由内到外的一个装饰过程,先执行内部的装饰器,再执行外部的装饰器。

# 定义装饰器

def make_div(func):

print('make_div装饰器执行了')

def inner():

result = '

' + func() + '
'

return result

return inner

def make_p(func):

print('make_p装饰器执行了')

def inner():

result = '

' + func() + '

'

return result

return inner

@make_div # 第二个执行,后执行外部的装饰器

@make_p # 第一个执行,先执行内部的装饰器

def content():

return '人生苦短,我用Python'

c = content() # 先用内部装饰器装饰,再用外部装饰器装饰

print(c)

# 原理剖析:content = make_div(make_p(content))

# make_div(make_p(content))中带入的 make_p(content) 即 make_p(content)中的inner,即make_div()是对 make_p 的 inner(已经返回的结果)进行装饰

运行结果:

make_p装饰器执行了

make_div装饰器执行了

人生苦短,我用Python

8) 带有参数的装饰器

① 带有参数的装饰器就是使用装饰器函数的时候可以指定参数,语法格式:@装饰器(参数...)。

② 使用带有参数的装饰器,其实是在装饰器外面又包裹了一个函数,使用该函数接收参数,返回是装饰器,因为@符号需要配合装饰器实例使用。

# 在装饰器网名又包裹了一个函数,使用该函数接收参数

# 定义函数

def return_decorator(flag):

# 装饰器只能接收一个参数并且是函数类型

# 定义装饰器

def decorator(func):

def inner(a,b):

if flag == '+':

print('正在努力执行加法计算')

elif flag == '-':

print('正在努力计算减法计算')

func(a,b)

return inner

# 当调用函数的时候可以返回一个装饰器decorator

return decorator # 函数返回值为一个装饰器,所以才能用@return_decorator('+'),因为@符号需要配合装饰器实例使用

@return_decorator('+')

def add_num(a,b):

result = a + b

print(result)

@return_decorator('-')

def sub_num(a,b):

result = a - b

print(result)

add_num(1,2)

sub_num(1,2)

# 原理剖析 @return_decorator('+') 等价于:

# 1. decorator = return_decorator('+') # return_decorator('+') 获得的是一个装饰器实例,所以可以用@

# 2. @decorator => add_num = decorator(add_num)

运行结果:

正在努力执行加法计算

3

正在努力计算减法计算

-1

9) 类装饰器的使用

① 使用类修饰已有函数

class MyDecorator(object):

def __init__(self,func):

self.__func = func

# 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用

def __call__(self, *args, **kwargs):

# 对已有函数进行封装

print('马上就有下班啦')

self.__func()

@MyDecorator # @MyDecorator => show = MyDecorator(show)

def show():

print('快要下雪啦')

# 执行show,就相当于执行MyDecorator类创建的实例对象,show() => 对象()

show()

运行结果:

马上就有下班啦

快要下雪啦

10) 装饰器应用场景

① 收集函数的操作或错误日志记录。

② 验证函数的使用权限。

③ 计算函数的运行时间。

④ 在ORM/DB模型操作时,通过属性方法动态地获取关联的数据。

⑤ 函数数据的缓存。

⑥ 定制函数的输入和输出(序列化和反序列化)。

二、我的自学路线

01 安装Python编辑器 [ 已整理 ]

02 Python编译器快捷键 [ 已整理 ]

03 Python基础 [ 已整理 ]

04 Python难点 [ 整理ing ]

05 Python常用的库 [ 整理ing ]

06 爬虫 [ 看视频ing ]

三、笔记目录

( ……更多笔记,见专栏 )

"♥我的笔记,希望对你有帮助♥"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!装饰器Python语言中的一个特性,它可以用来修改函数或类的行为。简而言之,装饰器就是一个用来装饰其他函数或类的函数。 装饰器的作用是在不修改被装饰对象源代码的情况下,给它添加额外的功能或行为。它可以让我们在代码中添加一些通用的功能,比如日志记录、性能分析、缓存等,而不需要在每个函数或类中都重复写相同的代码。 具体来说,装饰器是一个函数,它接受一个函数(或类)作为输入,并返回一个新的函数(或类)。这个新函数通常会在原函数的基础上做一些额外的操作,然后返回结果。 举个例子,假设我们有一个函数 `say_hello`,我们希望在每次调用这个函数时打印一条日志。我们可以定义一个装饰器函数 `log_decorator` 来实现这个功能: ```python def log_decorator(func): def wrapper(*args, **kwargs): print("Calling function: ", func.__name__) return func(*args, **kwargs) return wrapper @log_decorator def say_hello(): print("Hello, world!") say_hello() # 执行 say_hello 函数,并自动打印日志 ``` 在上面的例子中,`log_decorator` 装饰器定义了一个名为 `wrapper` 的新函数,它在调用被装饰的函数之前先打印一条日志,然后再调用原函数。最后,`log_decorator` 装饰器返回了这个新函数 `wrapper`。 通过在 `say_hello` 函数上使用 `@log_decorator`,我们将 `say_hello` 函数传递给了 `log_decorator` 装饰器,并创建了一个新的函数。当我们调用 `say_hello` 函数时,实际上是在调用被装饰后的 `wrapper` 函数,它会先打印日志,然后再执行原来的 `say_hello` 函数。 这就是装饰器的基本概念和用法。它可以帮助我们将代码中的一些通用功能抽象出来,并可以轻松地应用到多个函数或类上,提高代码的复用性和可维护性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值