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

天津 企业网站建设学习做网站教程

天津 企业网站建设,学习做网站教程,怎么做网站像淘宝这样的,软件开发常用架构描述符描述符也是面向进阶的一种#xff0c;由于它的涉及比较广#xff0c;所以单独讲。 一、描述符 描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议。 描述符的作用是用来代理另外一个类的属性#xf… 描述符描述符也是面向进阶的一种由于它的涉及比较广所以单独讲。 一、描述符 描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议。 描述符的作用是用来代理另外一个类的属性必须把描述符定义成一个类的类属性不能定义到构造函数中。 描述符分为两种一种是数据描述符至少实现了__get__()和__set__()另一种是非数据描述符没有实现__set__()。 1.描述符格式 class Foo: #在python3中任何类都是新式类,它只要实现了三种方法之一,那么这个类就被称作一个描述符def __get__(self, instance, owner): #调用一个属性时触发passdef __set__(self, instance, value): #为一个属性赋值时触发passdef __delete__(self, instance): #采用del删除属性时触发pass 2.描述符的使用 描述符该如何使用呢具体代码如下 class Foo: #描述符def __get__(self, instance, owner):print(我是get方法)def __set__(self, instance, value):print(我是set方法)def __delete__(self, instance):print(我是delete方法) class Bar:x Foo() #把描述符代理一个类的属性def __init__(self,n): self.x nb1 Bar(10) b1.x 11111 b1.x del b1.x 执行代码结果为 我是set方法 我是set方法 我是get方法 我是delete方法 可以看出在实例化时也会触发__set__方法因为在类Bar的初始化函数中self.x是被描述符代理的属性。那么对象b1中的属性字典中到底存不存在x这个值呢具体代码如下所示 class Foo(): #描述符def __get__(self, instance, owner):print(我是get方法)def __set__(self, instance, value):print(我是set方法)def __delete__(self, instance):print(我是delete方法) class Bar:x Foo()def __init__(self,n): self.x nb1 Bar(10) print(b1.__dict__) b1.x 11111 print(b1.__dict__) 执行结果为 我是set方法 {} 我是set方法 {} 这是什么情况无论是实例化操作还是赋值操作在对象b1的属性字典中仍然为空。正是因为描述符的关系它相当于把被描述符的类的调用属性操作、赋值操作、删除操作都赋予另一个类来实现跟本身类并没有关系当然这关系到优先级的问题。 3.描述符的优先级 我们要严格遵守优先级类属性数据描述符实例属性非数据描述符找不到的属性触发__getattr__()。 1我们先对类属性数据描述符进行分析具体代码如下 class Foo():def __get__(self, instance, owner):print(我是get方法)def __set__(self, instance, value):print(我是set方法)def __delete__(self, instance):print(我是delete方法) class Bar:x Foo()Bar.x111 print(Bar.x) #结果为111 上述代码打印结果仍为111并没有执行数据描述符是因为Bar类调用了本来要被描述符代理的属性x进行了修改。所有类属性的优先级比数据描述符高。 2数据描述符实例属性的分析代码如下 class Foo():def __get__(self, instance, owner):print(我是get方法)def __set__(self, instance, value):print(我是set方法)def __delete__(self, instance):print(我是delete方法) class Bar:x Foo()b1 Bar() b1.x #结果为我是get方法 b1.x 111 #结果为我是set方法 上述代码Foo类被定义成Bar类的类属性即对Bar类进行实例化实例属性只执行数据描述符的方法。说明了数据描述符的优先级高于实例属性。 3实例属性非数据描述符的分析代码如下 class Foo():def __get__(self, instance, owner):print(我是get方法) class Bar:x Foo()b1 Bar() b1.x 111 print(b1.__dict__) #结果为{x: 111} 上述代码可以看出实例给自己属性进行赋值操作可以在实例的属性字典中找到这说明了实例属性的优先级高于非数据描述符。 4非数据描述符找不到的属性触发__getattr__()的分析代码如下 class Foo():def __get__(self, instance, owner):print(我是get方法) class Bar:x Foo()def __getattr__(self, item):print(我是getattr方法) b1 Bar() b1.x #结果为我是get方法 b1.name #结果为我是getattr方法 上述代码可以看出找得到时触发__get__方法找不到就会触发__getattr__方法。说明了非数据描述符的优先级高于找不到的属性触发__getattr__()。 4.描述符的应用 描述符可以应用到哪些场合呢我们就来举个例子通过描述符机制来实现参数的赋值类型限制。即 class Typed:def __init__(self,key,expected_type):self.key keyself.expected_type expected_typedef __get__(self, instance, owner):print(get方法)return instance.__dict__[self.key]def __set__(self, instance, value):print(set方法)if not isinstance(value,self.expected_type):raise TypeError(你传入的类型不是%s %self.expected_type)instance.__dict__[self.key] valuedef __delete__(self, instance):print(delete方法)instance.__dict__.pop(self.key) class People:name Typed(name,str)age Typed(age,int)salary Typed(salary,float)def __init__(self,name,age,salary):self.name nameself.age ageself.salary salaryp1 People(alex,18,6666.66) p2 People(250,26,4568.55) #不符合赋值类型抛出异常 上述代码对象p1是满足参数的赋值类型所以会触发三次__set__方法。而对象p2不符合赋值类型就会抛出异常。 5.propetry 一个静态属性property本质就是实现了__get____set____delete__三种方法。 propetry有两种用法第一种即 class Foo:property #静态属性def AAA(self):print(get的时候运行)AAA.setterdef AAA(self,value):print(set的时候运行,value)AAA.deleterdef AAA(self):print(delete的时候运行) f1 Foo() f1.AAA f1.AAAaaa del f1.AAA 执行结果为 get的时候运行 set的时候运行 aaa delete的时候运行 上述代码中只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter。 第二种用法的代码实现如下 class Foo:def get_AAA(self):print(get的时候运行)def set_AAA(self,value):print(set的时候运行,value)def del_AAA(self):print(delete的时候运行)AAA property(get_AAA,set_AAA,del_AAA) #内置property三个参数与get,set,delete一一对应 f1 Foo() f1.AAA f1.AAAaaa del f1.AAA 执行结果为 get的时候运行 set的时候运行 aaa delete的时候运行 上述两种用法的结果都是一样的。 我们也可以利用描述符自定制property实现延时计算。我们先对一段代码进行分析来看看我们利用描述符自定制property该如何实现相同的目的。即 class Room:def __init__(self,name,width,length):self.name nameself.width widthself.length lengthproperty #areaproperty(area)def area(self):return self.width*self.length r1 Room(别墅,15,16) print(r1.area) #结果为240 在上述代码中property相当于实现了areaproperty(area)而property它是一个类这是不是相当于property类定义成Room类的类属性这不就是描述符的性质吗它既然是描述符那么它是数据描述符还是非数据描述符呢从结果它打印实例属性可以看出它是非数据描述符因为实例属性的优先级非数据描述符。假如我们自定制property不采用内置的静态属性property该如何实现上述代码即 class Lazyproperty:def __init__(self,func):self.func funcdef __get__(self, instance, owner):return self.func(instance) #instance实例本身 class Room:def __init__(self,name,width,length):self.name nameself.width widthself.length lengthLazyproperty #areaLazyproperty(area)def area(self):return self.width*self.length r1 Room(别墅,15,16) print(r1.area) #结果为240 上述代码中的Lazyproperty是我自定制的当然Lazyproperty类中我们只能定义成非数据描述符否则不会执行area方法。 我们继续利用自定制property来实现延时计算功能 class Lazyproperty:def __init__(self,func):self.func funcdef __get__(self, instance, owner):print(get)if instance is None: #被类调用必须写否则报错因为类没有实例return selfres self.func(instance) #instance实例本身setattr(instance,self.func.__name__,res) #缓存return res class Room:def __init__(self,name,width,length):self.name nameself.width widthself.length lengthLazyproperty #areaLazyproperty(area)def area(self):return self.width*self.length r1 Room(别墅,15,16) print(r1.area) #从字典里先找因为实例属性非数据描述符没有再去类的中找,然后出发了area的__get__方法 print(r1.area) #先从自己的属性字典找,找到了,是上次计算的结果,这样就不用每执行一次都去计算 上述代码实现了延时计算功能这样这不会每次都打印get的操作。描述符是可以实现大部分python类特性中的底层魔法,包括classmethod,staticmethd,property甚至是__slots__属性。  6.类的装饰器 类的装饰器与函数的装饰器性质是一样的类的装饰器分为无参装饰器和有参装饰器。 我们先来定义一个无参的装饰器即 def deco(func):print()func.x 1func.y 2return func deco #相当于Foo deco(Foo) class Foo:pass print(Foo.__dict__) 执行结果为 {__module__: __main__, __dict__: attribute __dict__ of Foo objects, __weakref__: attribute __weakref__ of Foo objects, __doc__: None, x: 1, y: 2} 上述代码当程序遇到deco就马上执行了Foodeco(Foo)可以在结果可以看出Foo类中的属性字典中有键值对x与y。 下面我们来介绍有参的装饰器该如何定义 def Typed(**kwargs):def deco(obj):for key,val in kwargs.items():setattr(obj,key,val)return objreturn decoTyped(x1,y2,z3) #1.Typed(x1,y2,z3)---deco 2.deco-----Foodeco(Foo) class Foo:pass print(Foo.__dict__)Typed(namealex) #deco----Bardeco(Bar) class Bar:pass print(Bar.name) 执行的结果为 {__module__: __main__, __dict__: attribute __dict__ of Foo objects, __weakref__: attribute __weakref__ of Foo objects, __doc__: None, x: 1, y: 2, z: 3} alex 上述代码定义了有参的装饰器函数Typed是用来接收所有参数的。 下面我们利用装饰器的应用以及描述符来实现参数的赋值类型限制即 class Typed:def __init__(self,key,expected_type):self.key keyself.expected_type expected_typedef __get__(self, instance, owner):print(get方法)return instance.__dict__[self.key]def __set__(self, instance, value):print(set方法)if not isinstance(value,self.expected_type):raise TypeError(你传入的类型不是%s %self.expected_type)instance.__dict__[self.key] valuedef __delete__(self, instance):print(delete方法)instance.__dict__.pop(self.key)def deco(**kwargs):def wrapper(obj):for key,val in kwargs.items():setattr(obj,key,Typed(key,val)) #Typed(key,val)描述符return objreturn wrapperdeco(name str,age int,salary float) class People:def __init__(self,name,age,salary):self.name nameself.age ageself.salary salaryp1 People(alex,20,6666.66) 实例化时触发了三次__set__方法。在描述符里也规定了参数的赋值类型。 转载于:https://www.cnblogs.com/lzc69/p/11316469.html
http://wiki.neutronadmin.com/news/121958/

相关文章:

  • 怎么做qq业务网站建网站多少钱一个平台
  • 湖南城乡住房建设厅网站网站建设可行性分析报告模板
  • 丹灶网站建设深圳装修公司口碑排名
  • 网站开发下载哪个同泰公司网站公司查询
  • 网站建设怎么链接表格大学生创新创业大赛报名入口
  • 深圳网站建设黄浦网络 骗子公司邮箱后缀正确的是以下
  • 招聘 网站建设表白网页在线生成制作源码
  • 建设部网站电话丽水微信网站建设公司
  • 新闻类的网站如何做优化我的世界做壁纸网站
  • 滕州网站建设猎头做单网站
  • 杭州网站建设品牌杭州seo相关网站
  • 中国林业建设协会网站wordpress 突然404
  • 做视频挣钱的网站趣快排seo是什么
  • 网站服务器配置要求夫妻找做伙食饭工作哪个网站好
  • 房地产管理局网站wordpress mysql pdo
  • 东莞做网站哪家好电商网站建设实训报告心得
  • 河南网站推广怎么做活动策划网站有哪些
  • 简洁大气企业网站做微信公众号整合网站
  • 微网站建设比较全面的是wordpress 封面
  • 开发网站需要什么硬件学校网站建设说明
  • 网站开发的需求分析论文采购系统有哪些
  • 枣庄市建设项目环评备案网站php做调查问卷网站
  • 做外贸找客户的网站关于网站建设费用
  • 做网站都需要哪些知识整站优化该怎么做
  • 网站设计图尺寸网站建设教程资源
  • 珠海网站建设哪个好薇音速企业名录搜索软件
  • 菜鸟学做网站的步骤工信部会抽查网站么
  • wordpress音乐站主题自建销售网站
  • 业余从事网站开发国家企业信息信用信息公示网
  • 河北省网络科技网站淘宝运营培训总结