python 修饰器 参数_Python修饰器

本文深入浅出地介绍了Python修饰器的概念,通过实例解析了修饰器的使用,包括无参数、有参数的修饰器,以及多重修饰器的运行原理。通过阅读,读者将能理解修饰器如何改变函数行为,并掌握其在实际编程中的应用。
摘要由CSDN通过智能技术生成

前话:

python的修饰器可以说是python语言最有灵性的一个功能了,看到网上有各种乱乱的文章,所以想自己写得亲民一下,如有错误请指出。

正文:

@fnc & 被修饰函数无参数

首先看一组简单的代码:

#修饰器

def dec(fn):

print("此处fn为函数",fn)

return fn

@dec

#被修饰函数

def my_fn():

return "函数返回值"

print(my_fn())

>>> 此处fn为函数

>>> 函数返回值

以上的代码的修饰过程相当于my_fn => dec(my_fn)

@fnc & 被修饰函数有参数

接下来为被修饰函数加参数:

def dec(fn):

print("此处fn为函数",fn)

return fn

@dec

def my_fn(a):

return "函数返回值为"+str(a)

print(my_fn('参数'))

>>> 此处fn为函数

>>> 函数返回值为参数

此处依然为my_fn => dec(my_fn)

[小插曲]@fnc() & 被修饰函数无/有参数

在修饰器和被修饰函数都带参数前,先准备一个小插曲:

def dec_out():

print('运行了dec_out')

def dec_in (b):

print("运行了dec_in")

return b

return dec_in

@dec_out()

def my_fn(a):

return "函数返回值为"+str(a)

print(my_fn('my_fn参数'))

>>> 运行了dec_out

>>> 运行了dec_in

>>> 函数返回值为my_fn参数

看到这么多函数不要晕哦,我来解释一下:

首先运行my_fn函数时先进入了修饰器

遇到了dec_out时发现修饰器位置是一个被执行的函数(带着括号),于是便执行了一下

修饰器就因为里面的return dec_in就等效成了@dec_out() => @dec_in

因此my_fn('my_fn参数')就等效成了dec_in(my_fn)('my_fn参数')

在这里休息一下,我来解答一下可能存在的疑惑:

Q:为什么上一个情况my_fn => dec(my_fn),这次是dec_in(my_fn)('my_fn参数')

A:注意细节哦,上一个是my_fn,这次是my_fn('my_fn参数')

[正餐]@fnc(*arg) & 被修饰函数无/有参数

到了正餐了,有了上一个的铺垫,这次的也可以理解了

def dec_out(a):

print("dec_out收到了",a)

def dec_in (b):

print("dec_in收到了",b)

return b

return dec_in

@dec_out("修饰器参数")

def my_fn(a):

return "函数返回值为"+str(a)

print(my_fn('my_fn参数'))

>>> dec_out收到了 修饰器参数

>>> dec_in收到了

>>> 函数返回值为my_fn参数

有没有预知到这次的结局呢?某种意义上很清楚明了了:

@dec_out("修饰器参数")在运行的因为return dec_in等效成了@dec_in,进而my_fn('my_fn参数')等效成了dec_in (my_fn)('my_fn参数')

这里我就不人肉DEBUG来给各位讲解了。

[加餐]多重@fnc(*arg) & 被修饰函数无/有参数

一下比较简单:

def dec_first(fn):

print("dec_first运行了")

return fn

def dec_second(fn):

print("dec_second运行了")

return fn

@dec_first

@dec_second

def my_fn():

return "my_fn运行了"

print(my_fn())

>>> dec_second运行了

>>> dec_first运行了

>>> my_fn运行了

从以上可以看出修饰器的运行顺序是从临近被修饰函数开始的。但是不要认为解释器是直接从第二个修饰器开始解释的。

请看一下代码:

def dec_first_out(a):

print("dec_first_out收到了",a)

def dec_first_in(fn):

print("dec_first_in运行了")

return fn

return dec_first_in

def dec_second(fn):

print("dec_second运行了")

return fn

@dec_first_out('第一个参数')

@dec_second

def my_fn():

return "my_fn运行了"

print(my_fn())

>>> dec_first_out收到了 第一个参数

>>> dec_second运行了

>>> dec_first_in运行了

>>> my_fn运行了

由此可以看出,解释器看到了最上方的修饰器处于运行状态(有括号)于是运行,后再按上面咱们发现的行为运行。

[最后的晚餐]被修饰的修饰器

听起来复杂,实际还是这么回事:

def dec_dec(fn):

print("dec_dec运行了")

return fn

@dec_dec

def dec(fn):

print("dec运行了")

return fn

@dec

def my_fn():

return "my_fn运行了"

print(my_fn())

>>> dec_dec运行了

>>> dec运行了

>>> my_fn运行了

看到这里应该已经清楚了吧,最有灵性的功能也是按部就班的执行的。

总结

总的来看,python的修饰器可以这么理解:

如果@后方不是一个函数名称,则运行到为一个函数名称为止,这种情况才会被解释成一个 参数为被修饰函数 的函数调用过程。(这么说是为了通俗明了,实际这么说欠妥)

多层的(闭包)函数作为修饰器要注意最终运行结果为一个函数名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值