python装饰器带参数函数_Python装饰器与带参数装饰器解析

Python装饰器与带参数装饰器解析

本文介绍Python装饰器与带参数装饰器,以及其与高阶函数的关系。

"""Python3 默认 unicode 编码,可以写中文以下代码请在 Python3 中运行"""

import time

import inspect

import sys

在 Python 中,装饰器是一个特殊的函数,它的输入必须是一个函数。

下面这个装饰器输入是一个函数X,然后返回值是函数Y,函数Y会将函数X运行 1000 次并且打印出其耗时。

def 装饰器(函数X):

def 函数Y(*X的参数, **X的kw参数):

start = time.time()

times = 1000

for _ in range(times):

ans = 函数X(*X的参数, **X的kw参数)

end = time.time()

print('run {} times use {}'.format(times, end - start))

return ans

return 函数Y

@装饰器

def sum1(array):

return sum(array)

此时的 sum1 等同于

>>> def sum1(array):

return sum(array)

>>> sum1 = 装饰器(sum1)

>>> sum1(array) 等同于 函数Y(array)

这里的 <函数Y> 是在 <装饰器> 的闭包环境中

也就是先将 的内容绑定给 <函数X>

再将 <装饰器> 的返回值 <函数Y> 绑定给 sum1

所以 运行 sum1(array) 会将

sum(array) 运行 1000 次并且打印其耗时

下面这个带参数装饰器,其返回值是一个装饰器,用这个装饰器装饰函数之后,可以运行该函数指定次数并且打印耗时。

def 带参数装饰器(times):

def 新装饰器(函数X):

def 函数Y(*X的参数, **X的kw参数):

start = time.time()

for _ in range(times):

# 运行次数由 带参数装饰器 的参数值决定

ans = 函数X(*X的参数, **X的kw参数)

end = time.time()

print('run {} times use {}'.format(times, end - start))

return ans

return 函数Y

return 新装饰器

@带参数装饰器(500)

def sum2(array):

return sum(array)

此时的 sum2 等同于

>>> def sum2(array):

return sum(array)

>>> sum2 = 带参数装饰器(500)(sum2)

>>> sum2(array) 等同于 函数Y(array)

这里的 <新装饰器> 是在 <带参数装饰器> 的闭包环境中

而 <函数Y> 又在 <新装饰器> 的闭包环境中

也就是先将 <新装饰器> 中的 times 变量设定为 500

然后将 的内容绑定给 <函数X>

最后将 <新装饰器> 的返回值 <函数Y> 绑定给 sum2

所以 运行 sum2(array) 会将

sum(array) 运行 times=500 次并且打印其耗时

Python的装饰器只限定了输入是函数,不对其输出进行任何限定。

def 坏蛋装饰器(函数X):

return "坏蛋装饰器返回值"

@坏蛋装饰器

def sum4(array):

return sum(array)

此时的 sum4 等同于

>>> def sum4(array):

return sum(array)

>>> sum4 = 坏蛋装饰器(sum4) = "坏蛋装饰器返回值"

>>> sum4(array) 会直接报错

下面代码测试下这些装饰器的作用,以及比较装饰器写法于高阶函数写法的不同。

def sum3(array):

return sum(array)

def test_sum():

array = list(range(1000))

# 装饰器写法在此!

print('装饰器写法结果:')

ans1 = sum1(array)

ans2 = sum2(array)

# 高阶函数写法在此!

# sum1 于 装饰器(sum3) 对应

# sum2 于 带参数装饰器(100)(sum3) 对应

print('高阶函数写法结果:')

ans3 = 装饰器(sum3)(array)

ans4 = 带参数装饰器(100)(sum3)(array)

新的装饰器 = 带参数装饰器(200)

装饰后函数 = 新的装饰器(sum3)

ans5 = 装饰后函数(array)

assert ans1 == ans2 == ans3 == ans4 == ans5

print('坏蛋装饰器的结果:')

print(type(sum4), sum4)

print('pass test')

if __name__ == "__main__":

test_sum()

运行结果:

装饰器写法结果:

run 1000 times use 0.009413957595825195

run 500 times use 0.009354591369628906

高阶函数写法结果:

run 1000 times use 0.015649080276489258

run 100 times use 0.0019309520721435547

run 200 times use 0.0029439926147460938

坏蛋装饰器的结果:

坏蛋装饰器返回值

pass test

Python中装饰器本身是一类特殊的高阶函数。其中:装饰器(使用@符号在函数定义前):输入:任意一个函数,例如上文的函数X

输出:没有特定要求,通常是该装饰器内定义的函数,例如上文的函数Y

函数Y输入通常是X的参数,这样方便调用函数X

函数Y输出是没有特定要求,可以与函数X的结果相同或不同

装饰器的输出会与函数X的名称绑定,例如函数sum4不再是函数而是坏蛋装饰器返回的字符串

带参数装饰器:输入:改变装饰器行为的变量

输出为装饰器

带参数装饰器更加灵活,可以对装饰器的行为进行修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值