当前位置: 首页 > news >正文

音乐图书馆网站建设长沙人才市场招聘网最新招聘

音乐图书馆网站建设,长沙人才市场招聘网最新招聘,可以玩h5的网站,杭州高端网站建设公司Python 装饰器详解#xff08;中#xff09; 转自#xff1a;https://blog.csdn.net/qq_27825451/article/details/84581272#xff0c;博主仅对其中 demo 实现中不适合python3 版本的语法进行修改#xff0c;并微调了排版#xff0c;本转载博客全部例程博主均已亲测可行…Python 装饰器详解中 转自https://blog.csdn.net/qq_27825451/article/details/84581272博主仅对其中 demo 实现中不适合python3 版本的语法进行修改并微调了排版本转载博客全部例程博主均已亲测可行。 Python 3.8.5 ubuntu 18.04 声明此文章为python装饰器详解——中篇上一篇文章中即详解装饰器——上篇 已经详细讲解了装饰器诞生的背景装饰器的定义、作用、应用场景本文将以实际例子为依托深入详解装饰器的各类实现包括函数装饰器、类装饰器、闭包、装饰器的嵌套四大块内容系列文章共分为 上、中、下 三篇。此为第二篇。 一、函数装饰器 前面提到过装饰器分为函数装饰器、类装饰器本节详细解释函数装饰器又分为两种情况因为函数装饰器可以装饰函数也可以装饰类。函数装饰器是最常见的故而最先讨论。 注意因为没有参数且无函数返回值的函数是最为简单的就如“上篇”所讨论的那样这里就不再叙述了本文主要讲的都是函数带有参数而且具有函数返回值的函数。 1. 函数装饰器装饰一个函数 假定有一个函数实现两个数的相加ab但是为了对这两个数相加的结果进行加密我们需要给函数添加额外的代码但是我们通过装饰器去实现要达到的效果是不是直接返回ab的结果而是进行进一步处理。代码如下 def MethodDecoration(function): #外层decoratorc150d200def wrapper(a,b): #内层wrapper。和add_function参数要一样resultfunction(a,b)resultresult*c/d #加密相当于添加额外功能return result #此处一定要返回值return wrapperMethodDecoration def add_function(a,b):return abresultadd_function(100,300) #函数调用 print(result)运行结果为300.0 即(100300)*150/200。 因为函数装饰器去装饰函数最为常见所以这里就不多再解释了按照前面上篇所讲的模板来即可但是因为被装饰的函数有参数而且具有返回值有两个点需要注意的 wrapper需要保证与add_function参数一致。因为返回的wrapper就是add_function所以要统一我们可以使用*arg和**kwargs去匹配任何参数 wrapper一定要返回值。因为add_function函数是需要返回值的。 2. 函数装饰器装饰一个类 在Python中从某种意义上来说函数和类是一样的因为它们都是对象python一切皆对象故而decorator的参数理所当然也可以传入一个类了。其中最经典的应用就是使用装饰器构造“单例模式”不明白单例模式的小伙伴可以参见下面这篇博文哦 一文详解“单例模式”及其python语言的实现 代码如下 def Singleton(cls): #这是第一层函数相当于模板中的Decorator.目的是要实现一个“装饰器”而且是对类型的装饰器cls:表示一个类名即所要设计的单例类名称因为python一切皆对象故而类名同样可以作为参数传递instance {}def singleton(*args, **kwargs): #这是第二层相当于wrapper要匹配参数if cls not in instance:instance[cls] cls(*args, **kwargs) #如果没有cls这个类则创建并且将这个cls所创建的实例保存在一个字典中return instance[cls] #返回创建的对象return singletonSingleton class Student(object):def __init__(self, name,age):self.namenameself.ageages1 Student(张三,23) s2 Student(李四,24) print((s1s2)) print(s1 is s2) print(id(s1),id(s2),sep )运行结果为 True True 140506831296352 140506831296352懂得单例模式的小伙伴可能一看就明白了上面的实现和我前面讲过的“装饰器模板”基本上一样第一层、第二层、返回值、参数匹配等。但是有的小伙伴可能会问这里我没有看到“添加额外功能”啊装饰器不是添加额外功能的么实际上“添加额外功能”是一种抽象的表述不是说一定要添加什么东西对被装饰的对象函数、类进行某种约束、处理、添加、删减等额外操作统称为添加额外功能。 这里约束了这个类型Student的创建主要这个类还没有创建实例就创建一个只要创建了就不在创建新的实例了只需要把之前创建的返回即可这是单例模式的思想。如果还是不明白下面再举一个“添加额外功能”的例子。 比如我有一个学生类在创建学生实例的时候有两个实例属性nameage现在要通过装饰器对类加以装饰使得在创建学生类的实例的时候还会添加height和weight两个属性代码如下 def ClassDecorator(cls): #第一层函数decoratorheight170weight65def wrapper(name,age): #第二层函数wrapper参数要和类的构造函数匹配scls(name,age)s.heightheight #添加两个额外属性s.weightweightreturn s #返回创建的对象因为类的构造函数是要返回实例的即有返回值return wrapperClassDecorator class Student:def __init__(self,name,age):self.namenameself.ageagestuStudent(张三,25) print(stu.name) print(stu.age) print(stu.height) #在 IDE中可能会有提示此处错误学生没有height和weight属性但是运行之后没错 print(stu.weight) #这就是python的魅力动态添加属性运行结果为 张三 25 170 65上面的例子和我们前面讲的装饰函数实在是太像了基本上和前面讲的模板一模一样。 **总结**函数装饰器不管是装饰函数、还是装饰类所遵循的思想原理是一样的实现的方式也是大同小异。注意函数装饰器装饰类实际上是装饰类的构造函数哦 二、类装饰器 前面定义的装饰器都是函数实际上类也可以是一个装饰器同样的道理类装饰器既可以装饰函数也可以装饰类。 1. 类装饰器装饰函数 先从一个简单的例子说起代码如下 class MethodDecorator:def __init__(self,function):self.functionfunctiondef __call__(self):print(开始)self.function()print(结束)MethodDecorator def myfunc():print(我是函数myfunc)myfunc()运行结果为 开始 我是函数myfunc 结束可能有的小伙伴很懵逼怎么会得到这样的结果我们一句一句来分析。 MethodDecorator def myfunc():print(我是函数myfunc)myfunc()这里相当于 myfuncMethodDecorator(myfunc)这样一写就明白了首先myfunc函数作为参数传递给类的构造函数因为调用类的构造函数自然会返回类的一个实例对象所以前面的myfunc实际上是类的一个实例对象然后调用myfunc这里虽然从形式上看依然是看起来还是调用函数但是本质上已经发生了变化它实际上一个对象调用这是类装饰器的本质很重要这就是为什么要定义__call__魔法方法。下面比如函数有返回值而且有参数要用类装饰器去装饰这个函数再用一个实例说明依然以上面的两个数据值和进行加密为例。 class MethodDecorator:def __init__(self,function): #这里相当于是第一层作用是将函数function传递进来self.functionfunctionself.c150 #这两个是需要加密的额外信息self.d200def __call__(self,a,b): #这相当于是第二层的wrapperprint(开始)resultself.function(a,b)resultresult*self.c/self.dprint(结束)return result #返回值MethodDecorator def add_function(a,b):return abresultadd_function(100,300) #这里相当于是函数调用 print(result)运行结果为 开始 结束 300.0总结实际上类装饰器所实现的功能在原理上和函数装饰器也没有太大的区别但是在代码实现上有所区别主要体现在两方面 类装饰器的构造函数__init__就相当于是第一层外层的 decorator传入需要装饰的对象作为参数 类装饰器的魔法方法__call__相当于是第二层内层的 wrapper。注意参数要统一有返回值需要返回值。 2. 类装饰器装饰类 依然以上面的给学生添加额外属性为例 class ClassDecorator:def __init__(self,cls): #这里相当于是第一层作用是将类名Student传递进来self.clsclsself.height170self.weight65def __call__(self,name,age): #这相当于是第二层的wrappersself.cls(name,age)s.heightself.height #动态添加属性增加额外信息s.weightself.weightreturn s #返回创建的学生实例sClassDecorator class Student:def __init__(self,name,age):self.namenameself.ageagestuStudent(张三,25) #注意这里的Student其实并不是一个类了而是装饰器返回的一个对象即这里的Student是ClassDecorator的实例#而且这里的Student(张三,25) 也不是构造函数了它的本质是装饰类的“对象调用” print(stu.name) print(stu.age) print(stu.height) print(stu.weight)输出结果为 张三 25 170 65总结这里的Student其实并不是一个类了而是装饰器返回的一个对象即这里的Student是ClassDecorator的实例而且这里的Student(‘张三’,25) 也不是构造函数了它的本质是装饰类的“对象调用”。 三、类装饰器的一般模板 通过上面的例子不管类装饰器是装饰类还是装饰函数它的模板都是大同小异的如下所示 class ClassDecorator: #类装饰器的名称def __init__(self,function_or_cls): #这里相当于是第一层作用是将需要装饰的类名、或者是函数名传递进来#这里可以添加额外信息self.clscls #或者是self.functionfunction,本质是要构造 一个属性#这里可以添加额外信息def __call__(self,name,age): #这相当于是第二层的wrapper参数需要与被装饰的类、被装饰的函数参数相同#这里可以增加额外信息sself.cls(name,age) #本质是调用原来的函数或者类的构造函数#resultself.function(a,b) #这里可以增加额外信息return s #返回创建的学生实例s注意类装饰器对象调用__call__是不可或缺的哦。 四、装饰器的缺点 前面讲了一大堆装饰器的优点简化代码代码复用增加额外功能等。那么装饰器优缺点吗当然有了世界上就没有完美无缺的东西那到底有一些什么样的缺点呢其实在上面的表述中已经提到了不知道小伙伴有没有注意 以下代码在上面的代码代码基础上执行上面代码这里就不重复一遍了 1. 函数装饰器装饰函数的时候 在上面源代码的基础之上添加下面的代码 print(add_function.__name__)输出为 wrapper这是为什么如果add_function没有被装饰器修饰的话则返回的应该为add_function这里为什么会返回第二层包装函数wrapper的名称这是因为装饰器的本质是add_functionMethodDecoration(add_function)而MethodDecoration返回的本来就是wrapper这就是上面结果的解释了。 2. 函数装饰器装饰类的时候 同样添加一句代码 print(Student.__name__)返回的结果是wrapper 出现这个现象的原因同上面1中所述的完全一样。 3. 类装饰器装饰类的时候 同样的添加下面一句话 print(add_function.__name__) #这里IDE不会提示错误哦IDE依然觉得这是个函数应该有__name__才对的显示 AttributeError: MethodDecorator object has no attribute __name__这里为什么突然不一样了呢正如前面所说的这里的add_function本质上是add_functionMethodDecorator(add_function)所以add_function本质上是装饰类的一个实例而MethodDecorator没有定义__name__属性那自然调用add_function.__name__就会显示没有__name__这个属性了。 4. 类装饰器装饰类的时候 print(Student.__name__) #这里IDE不会提示错误哦IDE依然觉得这是个类名应该有__name__才对的显示 AttributeError: ClassDecorator object has no attribute __name__原因同上面一样因为Student本质上是ClassDecorator的一个对象实例哦 装饰器的缺点总结 被函数装饰器所装饰的对象函数、类已经不再是它本身了虽然从形式上看没有变化本质上是函数装饰器的内部wrapper 被类装饰器所装饰的对象函数、类也不再是它本身了虽然从形式上看没有变化本质上是类装饰器的一个对象。 补充关于装饰器的嵌套装饰器与python闭包的关系我会在系列文章Python高级编程——装饰器Decorator详解下篇中继续讲解有兴趣的继续关注
http://www.sadfv.cn/news/91848/

相关文章:

  • 外贸企业网站红色风格哪里有未成年做的网站
  • 网站如何做优化排名电子政务网站建设的实验体会
  • php网站开发教程网怎么注册公司公众号微信号
  • 网站分屏布局设计东莞市企业网站制作服务机构
  • 如何做好一个企业网站设计新闻类网站排版网站建设
  • 电影网站如何做长尾关键词百度贴吧论坛
  • 做视频网站弹窗wordpress多重筛选并排序
  • 成都招聘网站制作帝国系统做企业网站
  • gis做图网站wordpress加载js
  • 律师事务所网站模板国外的自建网站怎么做
  • 淮安新网站制作郑州工程网官网最新版入口
  • 信阳百度推广公司电话东营网站搜索引擎优化
  • 网站开发人员岗位seo是什么地方
  • 营销型网站建设费用怎么这么大网站首页的导航栏
  • 优秀产品设计案例江门搜狗网站推广优化
  • 网站主题下载微信支付 网站开发
  • 建外做网站的公司平台设计是什么
  • 如何进行网站设计中国市场网
  • 阜康网站建设创建公众号的流程
  • 东台做网站哪家便宜网店推广方案范文
  • 高端定制网站开发需要多少钱色彩网站设计师
  • 网站开发三大元素如何设计网站中的上传功能
  • 基于html的个人网站的设计与实现论文正保建设工程教育网官网
  • 开源网站官网免费申请域名的步骤
  • 用wordpress建立的网站吗泰安
  • 做外贸有那些网站平台米拓cms 网站模板在哪
  • 网站上传好了如何做定向哈尔滨网站建设方案服务
  • 怎么做整人点不完的网站乐趣公园 wordpress
  • html5 单页网站网站建设维护成
  • 移动网站建设推广中国制造网怎么样