python装饰器代码深入讲解

python装饰器就是用于扩展原函数功能的一种函数,这个函数特殊的地方就是它的返回值也是一个函数,使用Python装饰器的一个好处就是:在不需要修改原函数代码的情况下,给函数增加新的功能。

先来看个例子:

def say():
 print('Nice day')

say()
# 这个函数的输出为:
Nice day

现在,我想在输出Nice day的前面再打印一行****************,类似下面的效果:

****************

Nice day

一般情况下,我可以修改上面的代码:

def say():
 print('****************')
 print('Nice day')

say()

可是,如果我忽然发现自己看错了需求,这时候又要把代码修改到原来的样子,庆幸的是我只是在原来函数的基础上增加了一行代码,想要回到原来的状态并不难,可如果我是修改了复杂的逻辑,代码有一百行呢,难道我还要一步步撤销吗?显然做不到,不过没关系,肯定还有别的办法:

def say():
 print('Nice day')

def outer(): # 重新定义一个新函数
 print('****************') # 处理新的逻辑
 say() # 再调用原来的函数

outer()
# 现在的输出为:
'''
****************
Nice day
'''

怎么样,看上去已经满足要求了吧,不过仔细一看,就能发现新的问题,如果不仅仅是say()函数需要打印****************,新来的talk()函数也需要呢,这时候我又要再写一个outer()函数吗?这会累坏丹丹的,所以得再想个办法:

def say():
 print('Nice day')

def talk():
 print('I am talk')

def outer(func): # 接收一个函数
 print('****************') # 处理新的逻辑
 func() # 调用传递过来的函数

outer(talk) # 把talk函数作为参数传递过去
# 输出结果如下:
'''
****************
I am talk
'''

这时,不管有几个函数需要打印****************,我直接把函数名传给outer()就可以啦,是不是方便很多^-^ 但是勤劳的丹丹会止步于此吗?肯定不会,于是又把代码做了如下修改:

def say():
 print('Nice day')

def outer(func):
 def inner():
 print('****************')
 func() # 相当于 say()
 return inner

s = outer(say) # 相当于 s = inner
s() # 相当于 inner()

猜猜这次的是输出是什么~当然还是和上面一样啦!其实这里只是把处理逻辑的部分封装在了一个函数里面,调用outer(say)的时候,把say传给outer,获得返回值inners,此时的s就相当于inners()也就相当于inner()所以会输出:

**************

Nice day

这就是一个最简单的装饰器啦,是不是很简单~ 但是我们每次在使用的时候还需要先赋值给一个变量(这里的s),然后再经由s调用,未免违反了丹丹“多一行代码都是累赘”的原则,所以我们再修改一下代码:

def outer(func):
 def inner():
 print('****************')
 func()
 return inner

@outer # 用outer装饰say
def say():
 print('Nice day')

say() # 调用say函数

我把outersay调换了一下位置,先定义了outer函数,@outer表示用outer装饰say,这样直接用say()就能实现我想先打印一行****************的功能了,如果不调换两个函数的位置,是会报NameError: name 'outer' is not defined的错误的噢(作用域的原因,outer未定义),这个应该算是复杂一点的装饰器了吧,哈哈
这时候很多细心同学肯定就会问了,你写的都是无参的呀,那如果我的函数有参数怎么办呢,参数还是不固定的又该怎么办呢?万能的python+聪明的丹丹当然可以解决:

# 带参数的装饰器
def outer(func):
 def inner(name):
 func(name)
 return inner

@outer
def say(name):
 print('name is %s.' % (name))

say('dandan')
# name is dandan.

不过这个参数个数是固定的,万一我又突发奇想,想多传一个hobby或者age怎么办呢?

# 带不定参数的装饰器
def outer(func):
 def inner(*args, **kwargs):
 func(*args, **kwargs)
 return inner

@outer
def say(name, age):
 print('name is %s, age is %d.' % (name, age))

@outer
def talk(name, age, hobby):
 print('name is %s, age is %d, hobby is %s.' % (name, age, hobby))

say('dandan', 18)
talk('dandan', 18, 'Coding')
'''
name is dandan, age is 18.
name is dandan, age is 18, hobby is Coding.
'''

如果我要新增的功能有很多,一个装饰器搞不定,怎么办呢?我可以同时使用多个装饰器吗?当然可以:

# 多个装饰器
def outer(func):
 def inner(*args, **kwargs):
 print('****************')
 func(*args, **kwargs)
 return inner

def outer2(func):
 def inner2(*args, **kwargs):
 print('这里有1w+新功能')
 func(*args, **kwargs)
 return inner2

@outer
@outer2
def say(name, age):
 print('name is %s, age is %d.' % (name, age))

@outer
@outer2
def talk(name, age, hobby):
 print('name is %s, age is %d, hobby is %s.' % (name, age, hobby))

say('dandan', 18)
talk('dandan', 18, 'Coding')
'''
****************
这里有1w+新功能
name is dandan, age is 18.
****************
这里有1w+新功能
name is dandan, age is 18, hobby is Coding.
'''

要注意的是,多个装饰器的执行顺序是从第一个装饰器开始,执行到最后一个装饰器,再执行函数本身。

到此这篇关于python装饰器代码深入讲解的文章就介绍到这了,更多相关python装饰器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python高阶函数与装饰器函数的深入讲解

    本文主要介绍的是Python高阶函数与装饰器函数的相关内容,分享给大家,下面话不多说了,来一起看看详细的介绍吧 高阶函数 1.可以使用函数对象作为参数的函数 2.或可以将函数作为返回值的函数 3.函数对象:定义好的函数,使用函数名调用(不要加括号) #将函数作为参数的高阶函数,通过传入不同的函数,可以使执行的结果不同 4.内置高阶函数 (1)map数据映射函数 map函数接收的是两个参数,一个函数,一个序列,其功能是将序列中的值处理再依次返回至列表内.其返回值为一个迭代器对象 (2)reduce

  • python 装饰器的实际作用有哪些

    接上一篇 终于知道python的装饰器是怎么回事,那在工作中,到底能干吗用呢? 尤其对我这个只会写写脚本又不做python开发的小测试/手动无辜脸. 先说结论,肯定是有用处滴. 一.自动化测试中使用 就拿写的自动化测试来说吧,如果我想统一的输出点东西,比如:case的运行时长,case名称等等,那就可以用起来. 首先,看下最简单的case,没有装饰器: import pytest def test_01(): a = 1 b = 2 assert a < b def test_02(): a =

  • Python classmethod装饰器原理及用法解析

    英文文档: classmethod(function) Return a class method for function. A class method receives the class as implicit first argument, just like an instance method receives the instance. To declare a class method, use this idiom: class C: @classmethod def f(c

  • 通俗易懂了解Python装饰器原理

    作用 装饰器可以用于用于装饰一个函数或方法,使得在不修改原函数.方法代码的前提下,为方法添加前置或后置操作: 例如突然想要计算一下各个函数的执行时间,又不希望在每一个函数中添加tim.time()来计算执行时间 用法 装饰器的写法网上很多,但是我觉得还是尽量先理解,再知道怎么写会比较好,所以会先说如何理解,在后面重写用法 实现 了解装饰器是如何实现的,远比会写装饰器更重要,简单的说装饰器就是接收一个函数对象,然后先执行前置操作,再执行函数,再执行后置操作: 这么说可能有些抽象,或者举一个不那么恰

  • python装饰器代码深入讲解

    python装饰器就是用于扩展原函数功能的一种函数,这个函数特殊的地方就是它的返回值也是一个函数,使用Python装饰器的一个好处就是:在不需要修改原函数代码的情况下,给函数增加新的功能. 先来看个例子: def say(): print('Nice day') say() # 这个函数的输出为: Nice day 现在,我想在输出Nice day的前面再打印一行****************,类似下面的效果: **************** Nice day 一般情况下,我可以修改上面的代

  • Python 装饰器代码解析

    前言: 以往看到我博客的小伙伴可能都知道,我的前言一般都是吐槽和讲废话环节,哈哈哈哈.今天难得休息,最近可真是太忙了,博主已经连续一年都在996了,所以最近没怎么学习新东西,只能回顾以往的旧知识了,上周一起工作的小伙伴扛不住996离职了,我们三人的小团队也正式解散了,哎.原本想着找时间好好整理一个关于关于接口自动化测试或ceph相关的东西.但由于篇幅过长这里目前可能不会着手写这方面东西.其实啊写是很简单的,主要例子难找.哈哈哈哈. 好了回归正题吧.看过我以往博客的小伙伴肯定见我用过@parame

  • python装饰器代码解析

    目录 1.装饰器通用模型 2.多个装饰器装饰的函数执行 3.带参数的装饰器 4.类装饰器 1.装饰器通用模型 def wrapper(fn):     def inner(*args, **kwargs):         ret = fn(*args, **kwargs)         return ret     return inner 装饰器几个关键点: 1.函数可以当参数传递 2.函数可以作为返回值进行返回 3.函数名称可以当成变量一样进行赋值操作 装饰器本质上是个闭包,在不改变原有

  • Python装饰器代码详解

    目录 一.理解装饰器 二.装饰器原型 1.不带参数的装饰器 2.带参数的被装饰的函数 3.带参数的装饰器 4.使用类作为装饰器 5.使用对象作为装饰器 6.多层装饰器的嵌套 总结 一.理解装饰器 所有东西都是对象(函数可以当做对象传递) 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. def function_one(): print("测试函数") #可以将一个函数赋值给一个变量,比如 foo =function_one #这里没有在使用小括号,因

  • Python 装饰器实现DRY(不重复代码)原则

    Python装饰器是一个消除冗余的强大工具.随着将功能模块化为大小合适的方法,即使是最复杂的工作流,装饰器也能使它变成简洁的功能. 例如让我们看看Django web框架,该框架处理请求的方法接收一个方法对象,返回一个响应对象: def handle_request(request): return HttpResponse("Hello, World") 我最近遇到一个案例,需要编写几个满足下述条件的api方法: 返回json响应 如果是GET请求,那么返回错误码 做为一个注册api

  • 通俗讲解python 装饰器

    装饰器其实一直是我的一个"老大难".这个知识点就放在那,但是拖延症... 其实在平常写写脚本的过程中,这个知识点你可能用到不多 但在面试的时候,这可是一个高频问题. 一.什么是装饰器 所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改. 这一句话理解起来可能没那么轻松,那先来看一个"傻瓜"函数. 放心,绝对不是"Hello World"! def hello(): print("你好,装饰器")

  • 举例讲解Python装饰器

    在Python里面,函数可以作为参数传入一个函数,函数也可以复制给变量,通过变量调用函数.装饰器可以扩展一个函数的功能,为函数做一个装饰器注解,可以把装饰器里面定义的功能于所有函数提前执行,提升代码的复用程度. 现在有这么个场景. 打卡 互联网公司里面有各种员工,程序员,前台...,程序员在打开电脑前,需要打卡,前台要早点来开门(我也不清楚,谁开门,这里假定,前台开门),前台开门前也需要打卡.也就是说,打卡是所有员工的最先的公共动作,那么可以把打卡这个功能抽出来作为公共逻辑. 普通函数调用方法

  • 使用Python装饰器在Django框架下去除冗余代码的教程

    Python装饰器是一个消除冗余的强大工具.随着将功能模块化为大小合适的方法,即使是最复杂的工作流,装饰器也能使它变成简洁的功能. 例如让我们看看Django web框架,该框架处理请求的方法接收一个方法对象,返回一个响应对象: def handle_request(request): return HttpResponse("Hello, World") 我最近遇到一个案例,需要编写几个满足下述条件的api方法: 返回json响应 如果是GET请求,那么返回错误码 做为一个注册api

  • python装饰器实现对异常代码出现进行自动监控的实现方法

    异常,不应该存在,但是我们有时候会遇到这样的情况,比如我们监控服务器的时候,每一秒去采集一次信息,那么有一秒没有采集到我们想要的信息,但是下一秒采集到了, 而后每次的采集都能采集到,就那么一次采集不到,我们应该针对这一次采集不到进行分析吗,这种的情况可以说无法重复出现,我们也无法避免,因为外界的因素太多太多,我们无法去控制这些外面的因素,所以我们会有这样的需求,一段时间内出现频率多少次,我们才能显示一次报警,或者说,一段时间内出现的频率达到我们的异常许可范围我们认为这样的属于异常,我们可以发出报

  • python 装饰器(Decorators)原理说明及操作代码

    目录 1 必要的2个核心操作 1.1 核心操作1, 函数内部可以定义函数 1.2 核心操作2 函数可以作为对象被输入输出 1.2.1 核心操作2的前置条件,函数是对象 1.2.2函数作为输入 1.2.3 函数作为输出 2 尝试构造装饰器 3装饰器定义的简写 本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是,在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我们先引入2个核心操作: 1 必要的2个核心操

随机推荐