首页 > 编程语言 >细说python装饰器

细说python装饰器

时间:2023-02-20 19:24:43浏览次数:43  
标签:细说 函数 python inner pass print 装饰 def

前言
什么是装饰器
实现原理
实现效果
适用场景
装饰器:
装饰器的写法
装饰器的拓展
装饰器的模板
什么是装饰器呢?
就是在特定条件下为某些函数再不改动函数体的时候为函数新添加一些功能,这就是装饰器

实现原理:
基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内置函数),执行函数时再在内层函数中执行闭包中的原函数

实现效果:
可以在你改变函数内部代码和调用的前提下,实现在函数执行和执行拓展功能

适用场景:
多个函数系统统一在执行前后定义一些功能

关于前言我们了解这么多就够了,然后小编带着大家推导出装饰器
装饰器:
装饰器的写法:
这里我们有一个需求,我们定义了5个函数,想在5个函数执行前和执行后都打印一句话:装饰器的学习。首先我们来写于一下没有装饰器的写法,话不多说直接上代码:

def a():
pass


def b():
pass


def c():
pass


def d():
pass


def e():
pass

先定义5个函数,再加上我们要打印的话:

def a():
print("装饰器的学习")
print("装饰器的学习")


def b():
print("装饰器的学习")
print("装饰器的学习")


def c():
print("装饰器的学习")
print("装饰器的学习")


def d():
print("装饰器的学习")
print("装饰器的学习")


def e():
print("装饰器的学习")
pass
print("装饰器的学习")


a()
b()
c()
d()
e()

运行一下:

 

发现运行成功,但我们想如果我要修改打印的话就要都修改一次,特别麻烦,而且,这是5个函数如果是500个,我们还要一个一个的去加吗?这就有我们的装饰器了,首先我用装饰器修改下,再给大家解释。

def outer(origin):
def inner():
print("装饰器的学习")
res = origin()
print("装饰器的学习")
return res

return inner


@outer
def a():
pass


@outer
def b():
pass


@outer
def c():
pass


@outer
def d():
pass


@outer
def e():
pass


a()
b()
c()
d()
e()

运行一下:

 

发现这样我们也成功了,接下来小编来个大家解释

首先:
我们要明白@的作用,那我们的函数a来举例子@的作用就是帮我们执行一次a=outer(a),首先python将把我们的a变成参数传给outer函数,运行后再赋值给a,这就是@的作用。

其次给大家解释一下自定的outer函数
我自己称这个函数为@下函数的补丁函数,也就是装饰器函数还是拿a函数举例子,首先a函数变成参数传给了我们的outer函数,outer里又嵌套了一个inner函数 ,然后将函数a赋值给res,然后用return语句返回出结果,外层函数返回inner函数,也就是将inner函数运行一次,这就是工作流程。

最后分别在各函数前加上装饰,最后运行出结果

这就是装饰器的写法。

装饰器的参数
这时我遇到一个问题如果函数内有参数而且每个函数的参数数量不同,我们应该怎末办,先看下面代码

def outer(origin):
def inner():
print("装饰器的学习")
res = origin()
print("装饰器的学习")
return res

return inner


@outer
def a(g, e):
pass


@outer
def b(w):
pass


@outer
def c(u, y, t):
pass


@outer
def d(c):
pass


@outer
def e():
pass


a()
b()
c()
d()
e()

这时我们运行一下

 

发现报错,是因为我们的装饰器内没有这两个参数,那可以在装饰器内设置两个参数,但问题是,有的函数内有3个参数,而有的函数内没有参数,那我们应该怎么办?

针对这个问题我们可以给装饰器设置动态参数,先看代码:

def outer(origin):
def inner(*args, **kwargs):
print("装饰器的学习")
res = origin(*args, **kwargs)
print("装饰器的学习")
return res

return inner


@outer
def a(a1):
print("我是一函数")


@outer
def b(a1, a2):
print("我是二函数")


@outer
def c(a5, a6, a7):
print("我是三函数")


a(1)
b(2, 3)
c(4, 5, 6)

因为函数太多了,小编有点麻烦就剪了几个函数,但道理是相同的,这时我们再运行一下

 

这样我们就成功了,以上就是装饰器的写法,接下来给大家拓展一下

装饰器的拓展:(functools模块)
首先给大家引入一下这时教给大家几个魔法方法

.__name__ 获取函数名字
.__doc__ 获取函数内的注释
接下来我们实战一下

def outer(origin):
def inner(*args, **kwargs):
# 我是一个装饰器函数
print("装饰器的学习")
res = origin(*args, **kwargs)
print("装饰器的学习")
return res

return inner


@outer
def c(a5, a6, a7):
# 我是个函数
print("我是三函数")


c(4, 5, 6)
print(c.__name__)
print(c.__doc__)

运行一下:

 

这时我们发现我要的是c函数,但给我反馈的是inner函数,这是为什么呢?

这就是工作原理,直接就把c函数装饰成了inner函数,那以后再工作中一定会要自己函数的名字,而不要我装饰后的函数,这样就可以让我们的函数装饰的更像,其实在以后中,都想装饰的更像,那我们应该怎末办?

这时就需要我们的第三方模块functools,直接上代码

import functools


def outer(origin):
@functools.wraps(origin)
def inner(*args, **kwargs):
# 我是一个装饰器函数
print("装饰器的学习")
res = origin(*args, **kwargs)
print("装饰器的学习")
return res

return inner


@outer
def c(a5, a6, a7):
# 我是个函数
print("我是三函数")


c(4, 5, 6)
print(c.__name__)
print(c.__doc__)

这时再运行一下

 

这时我们发现,我们伪装成功了,这样就会让我们的装饰更像。

装饰器模板:
接下来送给大家装饰器的模板,以后需要随时ctrl+c和ctrl+v

import functools


def outer(origin):
@functools.wraps(origin)
def inner(*args, **kwargs):
# 这里书写需要装饰的功能
res = origin(*args, **kwargs)
return res

return inner
记得要在需要装饰的函数前要写上@outer

标签:细说,函数,python,inner,pass,print,装饰,def
From: https://www.cnblogs.com/zuochuang/p/17138567.html

相关文章

  • 这一次,Python 真的有望告别 GIL 锁了?
    Python中有一把著名的锁——全局解释器锁(GlobalInterpreterLock,简写GIL),它的作用是防止多个本地线程同时执行Python字节码,这会导致Python无法实现真正的多线程执行......
  • python内置装饰器
    python有三个内置装饰器:@property,@classmethod,@staticmethod(一)@property这是用来修饰类的方法的,可以把类的方法变成可直接读/写的属性 相当于get和set方法我们......
  • 装饰器
    装饰器装饰器(Decorators)是Python的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。大多数初学者不知道......
  • Python 学习02 内置数据类型
    ......
  • Yum系列系统升级python版本
    问题描述系统可能携带的是python3.6,而自动化开发基线是python3.7就会导致部分包无法使用等问题升级python3.7查看当前系统python版本ls-al/usr/bin|greppython......
  • PYTHON将图片插入到excel
    一、案例1:insert_imageimportxlsxwriterbook=xlsxwriter.Workbook('E:\\test.xlsx')sheet=book.add_worksheet('demo')sheet.insert_image('D4','E:\\001.jpg')b......
  • python如何读取excel表数据
    @目录python读取excel表数据的方法:完整的程序代码python读取excel表数据的方法:首先安装Excel读取数据的库xlrd;然后获取Excel文件的位置并且读取进来;接着读取指定的行和列......
  • python 装饰器示例
    1defwrapper_log(func):2"""3无参装饰器,也可以写成有参装饰器,True或Flase标记是否调用日志模块4功能一:执行失败,打印并记录错误日志信息,定位bug......
  • python--matplotlib(2)
    前言 Matplotlib画图工具的官网地址是http://matplotlib.org/Python环境下实现Matlab制图功能的第三方库,需要numpy库的支持,支持用户方便设计出二维、三维数据的图形显示,制......
  • python之路73 vue框架 vue-cli创建项目、vue项目目录介绍、es6导入导出语法、登录功
    vue-cli创建项目前端做成项目---》使用工具(vue-cli),创建vue项目,单页面应用(spa),组件开发,把xx.vue,ts,saas,less---》编译---》在浏览器中执行vue-cli创建项目开发,在项......