文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python 装饰器

2023-01-30 21:58

关注

装饰器本质上是一个Python函数,它可以让其他函数在不雲要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

它经常用于有切面雲求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大畺与函数功能本身无关的雷同代码并继续重用。

概括的讲,装饰器的作用就是为已经存在的对象添加颉外的功能。


定义:

本质是函数,装饰器他函数,为器他函数添加附加功能。


原则:

不能修改被装饰函数的源代码

不能修改被装饰函数的调用方法


总结:

装饰器对被装饰的函数,是完全透明的,没有任何影响。


举个例子:

下面有一个函数,需要加一个功能,打印程序执行的时间

import time
def test1():
    #等待1秒,表示代码逻辑部分,这里直接简写了
    time.sleep(1)
    print('in the test1')

这个函数已经上线很久了,如果更改源代码,是有风险的。

这个时候,用装饰器,就可以解决这个问题。

import time
def timmer(func):
    def warpper(*args,**kwargs):
        start_time = time.time()
        func()
        stop_time = time.time()
        print('the func run time is %s' %(stop_time - start_time))
    return warpper

@timmer
def test1():
    time.sleep(1)
    print('in the test1')

test1()

执行输出

in the test1

the func run time is 1.0007095336914062


首先需要写一个装饰器函数,在被装饰的函数名上一行,加@装饰器函数名,就可以了


实现装饰器知识储备:

1.函数即"变量"

2.高级函数

  a.把一个函数名当作实参传给另外一个函数(不修改被装饰函数的源代码前提下,为其添加功能)

  b.返回值中包含函数名(不修改函数的调用方式)

3.嵌套函数


高阶函数+嵌套函数 = 装饰器


def bar():
    print('in the bar')

def test1(func):
    print(func)

test1(bar)

执行输出


得到的结果是一个内存地址。


def bar():
    print('in the bar')

def test1(func):
    print(func)
    func()

test1(bar)

执行输出


in the bar


func执行,得到一个内存地址,因为它是一个变量,函数即变量

func()执行,就是把内存地址的内容调取出来,得到in the bar


import time
def bar():
    time.sleep(1)
    print('in the bar')

def test1(func):
    start_time = time.time()
    #执行bar()函数
    func()
    stop_time = time.time()
    print('the func run time is %s' % (stop_time - start_time))

test1(bar)

执行输出

in the bar

the func run time is 1.000032901763916


test1(bar)执行的时候,把bar函数传进去了

那么test1函数体内的func就等同于bar函数

所以程序执行,输出了上面2行的结果。


上面的代码,貌似实现了装饰器的功能。源代码bar,并没有修改啊,但是违背了第2个原则,修改了函数的调用方法。

默认bar函数调用时,直接bar()就可以了,现在变成了test1(bar)。



import time
def bar():
    time.sleep(1)
    print('in the bar')

def test2(func):
    print(func)
    return func

print(test2(bar))

执行输出

function bar at 0x0000017DFD6E3E18

function bar at 0x0000017DFD6E3E18


返回的结果是一个内存地址


把执行方式改一下

t = test2(bar)
print(t)

执行输出

function bar at 0x0000017DFD6E3E18

in the bar


貌似没什么卵用


再改一下

t = test2(bar)
t()

执行输出

function bar at 0x0000017DFD6E3E18

in the bar


t()相当于执行了bar函数,貌似没啥卵用


再改一下

bar = test2(bar)
bar()

执行输出

function bar at 0x0000017DFD6E3E18

in the bar


结果和上面是一样的,但是调用方式,发现和原函数调用是一模一样的。

下面打印一下bar的类型是变量还是函数

bar = test2(bar)
print(type(bar))
bar()

执行输出

blob.png

可以看出,bar赋值之后,变成了函数,为什么呢?因为test2本身就是函数,所以它当然是函数了。

所以才可以执行bar()


但是bar()已经不是原来的bar函数了,而是被装饰过的函数。

因为原来的bar执行,只会输出 in the bar



函数嵌套

定义:在一个函数中定义了另外一个函数


在一个函数体内,用def去声明一个新的函数,而不是去调用它。

下面是一个嵌套函数

def foo():
    print('in the foo')
    def bar():
        print('in the bar')

    bar()

foo()

执行输出

in the foo

in the bar





阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯