python转义字符退格,python否定符号
通过使用基于描述符的python描述符,可以定义用于触发自动执行的代码。它像是一个对象属性操作(访问、赋值、删除)的代理类一样前面介绍的属性是一种描述符。
大致流程如下。
包含一个或多个__get__()、__set__()和__delete__()方法的描述符类D
将描述符类D的实例对象D分配给要代理的另一个类的属性attr。即attr=D()
然后,访问attr属性,赋值并删除它。描述符类中的__get__()、__set__()、和__delete__()方法只是)。
描述符类非常简单。只要该类包含以下一个或多个方法,它就可以用作属性操作的代理,即使满足描述符协议或描述符类:
class descriptor(3360 def _ get _)self,instance,owner)。def__set_)自身,实例,值
另外,请注意不要混淆__delete__和__del__。前者是实现描述符协议的方法,后者是对象销毁函数(也叫析构函数)。
不考虑这些方法的参数,请看一个例子。
类描述符(3360 def _ get _) from,instance,owner):print(self:% s(n instance 3360% s()nowner))类s: #描述符的示例对象是属性attr=的描述符
Self: _ main _。0x 030 c 02 d0实例处的描述符对象:_ main _。sobjectat0x 030 c 030 ab 0 owner 3360 class -self:stance:none owner:class _ _ main _。s很容易理解。
在这个方法中,结果分别显示三个参数self、instance和owner的内容。它们具有以下等价关系。
S1 . attr-描述符。_ _ get _ (s.attr,S1,s ) s.attr-descriptor。_ _ get _ (s.attr,None,s))
Self:描述符对象本身,即代理类s的属性attr。
Instance:委托类的实例对象。因此,如果要访问class属性(class.attr),它是None。
Owner:描述符对象所属的类实际上是实例所属的类,即type(instance)。这里解释几个相关的功能。
描述符:它既是描述符类,也是代理。
s是另一个类,宿主类、客户类或参数中的所有者。
Attr=Descriptor():描述符的实例对象,其中Attr是主机类属性或参数的自身。
S1:托管类instant对象,也就是参数中的实例,大概可以根据描述符的功能,如上定义每个角色。当然,角色的定义是没有限制的。
描述符的作用是什么?定义类后,可以访问、分配和删除其属性。这些操作也适用于此实例对象。
例如,Foo类:
class foo(:f=foo)a=f . bar # access attribute f . bar=b # assign attribute del f . bar # delete attribute descriptor在执行这三个操作中起作用。
访问X.D .时会自动调用descriptor类的__get__。
当x.d被赋值后,descriptor类的__set__会被自动调用。
当X.D .被删除时,descriptor类的__delete__会被自动调用。请考虑一下,如果在X所属的类中定义了__getattr__,__setattr__,__delattr__,会发生什么情况。这是一个声明。不断尝试。
考虑一下,如果X所属的类没有定义,但是它的父类定义了这些方法,那么谁来生效。你可以自己测试或者参考我下一篇文章。
例1:原代码假设有一个学生类,需要记录stuid、name、score1、score2、score3信息。
class Student():def _ _ init _ _(self,stuid,name,score1,score2,score 3):self . stuid=stuid self.name=name self.score1=score 1 self.score2=score 2 self . score 3=score 3 def return me(self):return %s,% s,%i,% I ,% I% (self.stuid,self . name,self . score 1,self . score 2,score 1-score 3)stu=Student( 2010 1 120 , 67,77,88
然后修改__init__():
class Student():def _ _ init _ _(self,stuid,name,score1,score2,score 3):self。stuid=stuid自我。姓名=姓名如果0=分数1=100:自我。分数1=分数1否则:提高值错误(分数不在[0,100])如果0=分数2=100:self。分数2=分数2否则:提高值错误(分数不在[0,100])如果0=分数3=100:self。分数3=分数3这个修改对于初始化学生对象时有效,但计算机编程语言中属性的赋值太过自由,之后可以随意赋值:
stu=学生( 20101120 ,马龙,67,77,88)斯图。分数1=-23打印(stu。还我())使用财产使用财产或者自定义的getter、setter或运算符__getattr__,__setattr__重载都能解决上面的问题,保证无法赋值超出0到100范围内的数值。
class Student():def _ _ init _ _(self,stuid,name,score1,score2,score 3):self。stuid=stuid自我。name=name self ._score1=score1 self ._score2=score2 self ._ score 3=score 3 def get _ score 1(self):返回自我._score1 def set_score1(self,score):如果0=分数=100:自我._ score 1=score else:提升值错误(分数不在[0,100]) def get_score2(self):返回自我._score2 def set_score2(self,score):如果0=分数=100:自我._ score 2=score else:raise value error( score not in[0,100]) def get_score3(self):返回自我._score3 def set_score3(self,score):如果0=分数=100:自我._ score 3=score else:raise value error( score not in[0,100])score 1=property(get _ score 1,set _ score 1)score 2=property(get _ score 2,set _ score 2)score 3=property(get _ score 3,set _ score 3)def return me(self):return %s,% s,%i,%i,%i % ( self.stuid,self.name,self.score1,self.score2,self.score3)下面测试时将抛出异常。
stu=学生( 20101120 ,马龙,67,77,88)打印(斯图。还我())斯图。分数1=-23但很显然,上面的重复代码太多了。
使用描述符如果使用描述符,将很容易解决上面的问题。只需将得分1、得分2、得分3交给描述符类托管即可。
从weakref导入WeakKeyDictionaryclass Score(): 分数应在[0,100] def _ _ init _ _(self):self。Score=weakkeydicturing()# self。Score={ } def _ _ get _ _(self,instance,owner):返回self。Score[instance]def _ _ set _ _(self,instance,value):if 0=value=100:self。Score[instance]=value else:提升值错误(分数不在[0,100])类学生():#托管属性定义在类级别上score1=Score()score2=Score()Score 3=Score()def _ _ init _ _(self,stuid,name,Score 1,Score 2,score 3):self。stuid=stuid self . name=name self . score 1=得分1 self.score2=得分2 self。score 3=score 3 def return me(self):return %s,% s,%i,%i % ( self.stuid,self。名字,自我。分数1,自我。分数2,自我。分数3)stu=学生( 2010 11 20 ,马龙,67,77,88)打印(斯图。还我())斯图。分数1=-23很明显地,它们的代码被完整地复用了。这里得分1、得分2、得分3被描述符类得分托管了,这3个分值分别被放进了得分实例对象的词典中(是单独存放它们还是使用词典数据结构来保存,取决于你)。
另外,上面使用了弱引用的字典,因为每个属性只在描述符对象中才会被用上,为了保证学生对象被销毁的时候能释放这些资源,所以采用弱引用,避免出现内存泄漏。
参考资料计算机编程语言描述符去神秘化
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。