python cls_搞定三大神器之 Python 装饰器

本文详细介绍Python装饰器的概念、结构及应用场景,包括如何装饰函数和类,实现单例模式,并进行装饰器层叠使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原标题:搞定三大神器之 Python 装饰器

来自公众号: Python与算法社区

学会 Python 装饰器

装饰器,几乎各大Python框架中都能看到它的身影,足以表明它的价值!它有动态改变函数或类功能的魔力!

本专题的目录:

学会 Python 装饰器

1 什么是装饰器

2 装饰器的结构

3 为什么要这样

4 装饰一个函数

5 装饰一个类

6 装饰器层叠

7 温馨提醒

总结

1 什么是装饰器

对于受到封装的原函数比如 f 来说,装饰器能够在 f 函数 执行前或者 执行后分别运行一些代码。

2 装饰器的结构

装饰器也是一个函数,它装饰原函数 f 或类 cls 后,再返回一个函数 g

装饰一个函数:

defdecorator(f):

# 定义要返回的函数

defg:

print( '函数f执行前的动作')

f

print( '函数f执行后的动作')

returng

装饰一个类:

defdecorator(cls):

# 定义要返回的函数

defg:

print( '类cls执行前的动作')

f

print( '类cls执行后的动作')

returng

使用装饰器很简单,@+自定义装饰器 装饰要想装饰的函数。

3 为什么要这样

要想理解装饰器为什么要有这种结构,要首先想明白装饰器的目标是什么。

它的价值在于为原函数 f 增加一些行为,前提必须不能破坏函数 f ,所以肯定不能改变f的内部结构,所以只能在调用f前后定义一些行为。

同时,装饰器函数 decorator 返回值又是什么?你可以思考下,返回一个函数是再好不过的了,它包装了原函数 f .

4 装饰一个函数

printStar函数接收一个函数 f ,返回值也是一个函数,所以满足装饰器的结构要求,所以printStar是一个装饰器。

defprintStar(f):

defg:

print( '*'* 20)

f

print( '*'* 20)

returng

printStar装饰器实现f函数执行前、后各打印20个*字符。

使用printStar:

@printStar

deff:

print( 'hello world')

调用:

if__name__ == '__main__':

### 改变函数功能

f

打印结果:

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

hello world

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

可以很方便的装饰要想装饰的其他函数,如下:

@printStar

defg:

print( 'welcome to Python')

5 装饰一个类

除了可以装饰函数f外,还可以装饰类cls,两者原理都是一样的。

下面给出一个装饰器实现单例模式的例子,所谓单例就是类只有唯一实例,不能有第二个。

defsingleton(cls):

instance = {}

defget_instance(*args, **kwargs):

ifcls notininstance:

instance[cls] = cls(*args, **kwargs)

returninstance[cls]

returnget_instance

定义字典 instance ,键值对分别为类和实例,这样确保只cls一次。

使用装饰器singleton修饰类:

@singleton

classCorePoint:

pass

测试:

if__name__ == '__main__':

### 改变类的功能

c1 = CorePoint

c2 = CorePoint

print(c1 isc2) # True

6 装饰器层叠

上面原函数f不仅能被一个装饰器修饰,还能被n多个装饰器修饰。

下面再定义一个装饰器printLine,被修饰函数执行前后打印20个 -

defprintLine(f):

defg:

print( '-'* 20)

f

print( '-'* 20)

returng

使用上文定义好的 printStar 和 printLine 同时装饰函数f:

@printStar

@printLine

deff:

print( 'hello world')

此时再调用函数f:

if__name__ == '__main__':

### 改变函数功能

f

打印结果:

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

--------------------

hello world

--------------------

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

f被装饰后,先打印*,再打印 -

层叠多一层,原函数f就变强大一层。使用装饰器,还能实现功能抽离,进一步实现松耦合。

7 温馨提醒

打印原函数f的名字 __name__ ,结果为 f

In [ 1]: deff:

...: pass

In [ 4]: f.__name__

Out[ 4]: 'f'

但是,被装饰后函数名字f变为g,这不是我们希望的!

@printStar

deff:

pass

f

f.__name__ # g

Python提供的解决方案:使用functools模块中的 wraps 装饰器:

fromfunctools importwraps

defprintStar(f):

@wraps(f)

defg:

print( '*'* 20)

f

print( '*'* 20)

returng

此时再打印被装饰后f的名字,显示f,正常!

总结

学会 Python 装饰器

1 什么是装饰器

2 装饰器的结构

3 为什么要这样

4 装饰一个函数

5 装饰一个类

6 装饰器层叠

7 温馨提醒

总结

以上就是装饰器的核心使用逻辑专题,希望能帮助到各位读者,若觉得有用,欢迎三连支持。咱们下个专题再见! 返回搜狐,查看更多

责任编辑:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值