Maison  >  Article  >  développement back-end  >  descripteur python descripteur(2)

descripteur python descripteur(2)

黄舟
黄舟original
2016-12-23 17:38:571265parcourir

def __init__( self,getf,setf,delf,doc):

       self.getf=getf

       self.setf=setf

       self.delf=delf

       self.doc=doc

   def __get__(self ,instance,own=None):
       si l'instance est None :
           return self
       si  self.getf est None :
           raise AttributeError
       return self.getf( exemple)
   def __set__(self,instance,value):
       if self.setf est None:
           raise AttributeError
       self.setf(instance,value)
   def __del__(self,instance):
       if self.delf est None:
           raise AttributeError    
       self.delf(instance)
class StaticMethod(object):
   def __init__(self,func):
       self.func=func
   def __get__(self,instance,own=None):
       return self.func
class ClassMethod(object):
   def __init__(self,func):
       self.func=func
   def __get__(self,instance,own=None):
       if own vaut None:
           own=type(instance)
       def callfunc(*args):
          return self.func(own, *args)
       return callfunc


为属性值设置别名

有时候你想用一个属性名作为另一个属性名的别名,比如设置一些属性的默认

class DefaultAlias(object):

   def __init__(self, nom):

       self.name=nom

   def __get__(self,instance,own):

       si l'instance est None :  #类属性访问时

           return self

       return getattr(instance,self.name).title()
class Person(object):
   def __init__(self,name,aliasname=None):
       self.name=name
       if aliasname n'est pas None :
           self.aliasname=aliasname
   aliasname =DefaultAlias('nom')
>>> p=Personne('sam')
>>> p.aliasname
'Sam'
>>> p.aliasname='jack'
>>> p.aliasname
'jack'
>>> del p.aliasname
>>> p.aliasname
'Sam'


这样就为属性name设置了一个别名aliasname,或者说把aliasname的值存储在了name中。DefaultAlias并不是数据描述符,因为它Il s'agit d'un ensemble de données non-données. Il s'agit d'un ensemble de données non-données.属性,而且实例属性会覆盖掉类属性。这样Nom d'alias现出来。

对于某些开发的类,如果可以用新名称来命名方法和属性,同时保留旧名字的可用性。

class OldAlias(object):
   def __init__(self,name,oldname):
       self.name=name
       self.oldname=oldname
   def _warn(self):
print 'use %r,not %r'%(self.name,self.oldname)
   def __get__(self,instance,own):
       self._warn()
      si l'instance est Aucune :  
           return self
       return getattr(instance,self.name)
   def __set__(self,instance,value):
       self._warn()
       setattr(instance,self.name,value)
   def __del__(self,instance):
       self._warn()
       delattr(instance,self.name)
class NewClass(object):
   def __init__(self,newname):
       self.newname=newname
   oldname=OldAlias('newname','oldname')
>>> c=NewClass('a')
>>> c.oldname
utilisez 'newname', pas 'oldname'
'a'

使用这个类的旧代码会使用类属性oldname,同时一个警告信息被打印,鼓励用户使用新属性newname。

缓存属性值

根据需求计算实例属性或类属性的值,并提供自动化的缓存。

classe CachedAttribute(object):
   def __init__(self,method,name=None):
       self.method=method
       self.name=name if name else method.__name__
   def __get__(self,instance,own):
       si l'instance est None :
           return self
       result=self.method(instance)
       setattr(instance,self.name,result)
       return result
class MyObject(object) :
   def __init__(self,n):
       self.n=n
   @CachedAttribute
   def square(self):
       return self.n*self.n
> >> m=MonObjet(2)
>>> m.carré
4
>>> m.n=5
>>> m.carré
4
>>> del m.square
>>> m.square
25

在首次访问m.square后,square属性就被缓存在实例m中,当改变实例属性n时,square属性不会改变。如果需要清除

class CachedClassAttribute(CachedAttribute):

   def __get__ (self,instance,own):

       return super(CachedClassAttribute,self).__get__(own,own)
class MyClass(object):
   class_attr=24
   @CachedClassAttribute
   def square (cls):
       return cls.class_attr*cls.class_attr


这样类的所有实例都有同样的缓存值了:

>>& gt; a=MaClasse()

>>> b=MaClasse()

>>> a.carré
>>> imprimer a.square
576
>>> imprimer b.square
576
>>> print MyClass.square
576


 以上就是python描述符descriptor(二)的内容,更多相关内容请关注PHP中文网(www.php.cn )!


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn