python装饰器详解
发布日期:2021-06-27 12:56:16
浏览次数:53
分类:技术文章
本文共 3431 字,大约阅读时间需要 11 分钟。
一、函数名的运用
函数名是⼀个变量,但它是⼀个特殊的变量。与括号配合可以执⾏函数的变量
1. 做变量
def func(): print('呵呵')a = func # 把函数当成变量赋值给另外一个变量a() # 通过变量a调用函数
2. 做容器元素
def func1(): print('func1')def func2(): print('func2') def func3(): print('func3') def func4(): print('func4')list1 = [func1, func2, func3, func4]for i in list1: i()
3. 做参
def func1(): print('func1')def func2(arg): print('start') arg() # 执行传递进来的arg print('end')func2(func1) # 把func1当成参数传递给func2
4. 做返回值
def func1(): print('这里是func1') def func2(): print('这里是func2') return func2 # 把func2当成返回值返回ret = func1() # 调用func1,把返回值赋值给retret() # 调用ret
二、闭包
**1、定义:**一个内层函数中,引用了外层函数(非全局)的变量,这个内层函数就可以成为闭包。在Python中,我们可以使用__closure__来检测函数是否是闭包。
2、例子:def print_msg(msg): # 这是外层函数 def printer(): # 这是内层函数 print(msg) return printer # 返回内层函数func = print_msg("Hello") #返回printer变量func() #实际上执行是printer()函数
现在我们进行如下操作:
>>> del print_msg>>> func()Hello>>> print_msg("Hello")Traceback (most recent call last):...NameError: name 'print_msg' is not defined
总结:
如果⼀个函数执⾏完毕,则这个函数中的变量以及局部命名空间中的内容都将会被销毁。在闭包中内部函数会引用外层函数的变量,而且这个变量将不会随着外层函数的结束而销毁,它会在内存中保留。也就是说,闭包函数可以保留其用到的变量的引用。三、装饰器
1、开放封闭原则是指对扩展代码的功能是开放的,但是对修改源代码是封闭的。这样的软件设计思路可以保证我们更好的开发和维护我们的代码。
2、利用闭包解释装饰器:def c(): print('11111111')def a(func): def b(): print('aaaa') func() return bc = a(c) # 运行步骤:a(c)=>func()=c() =>返回值赋值 c=bc() #实际运行 b()=>打印aaa=>运行c()=>打印1111111
3、装饰器规范写法如下:
def a(func): def b(): print(1111') func() return b@a # 装饰器语法def c(): print('cccccc!') # 调用被装饰函数c()
4、带参数的装饰器
def f1(func): # f1是我们定义的装饰器函数,func是被装饰的函数 def f2(*arg, **kwargs): # *args和**kwargs是被装饰函数的参数 func(*arg, **kwargs) return f2
5、装饰器修复技术
**(1)**被装饰的函数最终都会失去本来的__doc__等信息, Python给我们提供了一个修复被装饰函数的工具。在装饰器内部加入 @wraps(func)进行修复 (2)例子:def a(func): @wraps(func) #可以将这个除去试试 def b(): print('洒点水') func() return b@a # 装饰器语法糖def create_people(): """这是一个女娲造人的功能函数""" print('女娲真厉害,捏个泥吹口气就成了人!')create_people()print(create_people.__doc__)print(create_people.__name__)
6、多个装饰器修饰一个函数执行顺序为从下至上
7、类装饰器: (1)基础知识:__init__和__call__分别为类中的初始函数和直接调用函数,都属于魔法函数(python内置的) (2)实例:class D(object): def __init__(self, a=None): #初始函数,调用类首先执行这个函数 self.a = a self.mode = "装饰" def __call__(self, *args, **kwargs): if self.mode == "装饰": self.func = args[0] # 默认第一个参数是被装饰的函数 self.mode = "调用" return self # 当self.mode == "调用"时,执行下面的代码(也就是调用使用类装饰的函数时执行) if self.a: print("欢迎来到{}页面。".format(self.a)) else: print("欢迎来到首页。") self.func(*args, **kwargs)@D()def index(name): print("Hello {}.".format(name)) if __name__ == '__main__': index('张三') #调用时调用类中的__call__函数
8、property属性方法
(1)我们把类中的一个只读属性定义为property属性方法,只有在访问它时才参与计算,一旦访问了该属性,我们就把这个值缓存起来,下次再访问的时候无需重新计算。 (2)例子:class lazyproperty: def __init__(self, func): self.func = func def __get__(self, instance, owner): if instance is None: return self else: value = self.func(instance) setattr(instance, self.func.__name__, value) return valueimport mathclass Circle: def __init__(self, radius): self.radius = radius @lazyproperty def area(self): print('计算面积') return math.pi * self.radius ** 2c1 = Circle(10)print(c1.area)print(c1.area)#执行这个会发现这一步只返回了值,没有重新执行函数。
转载地址:https://blog.csdn.net/weixin_43458262/article/details/102724638 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月03日 16时35分27秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
PHP防止注入攻击
2019-04-27
多路IO复用模型 select epoll 等
2019-04-27
Linux Epoll介绍和程序实例
2019-04-27
output_buffering详细介绍
2019-04-27
php缓冲 output_buffering和ob_start
2019-04-27
php error_reporting 详解
2019-04-27
剖析PHP中的输出缓冲
2019-04-27
HTTP响应头不缓存
2019-04-27
PHP安装扩展mcrypt以及相关依赖项 【PHP安装PECL扩展的方法】
2019-04-27
Javascript到PHP加密通讯的简单实现
2019-04-27
德国SNS交友/视频网站Poppen.de的技术架构分享
2019-04-27
UNIX环境编程
2019-04-27
一笔画问题【数据结构-图论】
2019-04-27
红黑树
2019-04-27
安装多个gcc
2019-04-27
Linux0.01内核根目录Makefile注释
2019-04-27
【CSDN2012年度博客之星】需要您的一票,感谢大家的支持
2019-04-27
PHP对于浮点型的数据需要用不同的方法去解决
2019-04-27
Tokyo Cabinet 安装
2019-04-27
Flink在美团的应用与实践听课笔记
2019-04-27