首頁  >  文章  >  後端開發  >  python描述子descriptor(二)

python描述子descriptor(二)

黄舟
黄舟原創
2016-12-23 17:38:571273瀏覽

python 內建的介面

python 內建的一些介面對象,PROperty、staticmethod、classmethod,python 實作如下:

class Property(object):
 getf=getf
       self.setf=setf
       self.delf=delf
       self。 None:
           返回self
       如果self.getf是None :
           引發AttributeError
       return self.getf(instance)
  def __        引發AttributeError
       self.setf (實例,值)
   def __del__(self ,instance ):
       如果self.delf 為None:
           引發AttributeError    
 f,func):
       self.func=func
   def __get__(self, instance, own=None):
       返回self.func
class ClassMethod(object):
   def __init__(self,func):
   sel       if own is None :
           own=type(instance)
       def callfunc(*args):
          return 1.
        

作為屬性值設定別名

有時你會想用一個屬性名稱作為另一個屬性名稱的別名,例如設定一些屬性的預設值必須和其他屬性的目前值一樣,而且還需要獨立的設定和刪除。

class DefaultAlias(object):
   def __init__(self,name):
       self.name=name
  我           return self
       return getattr(instance,self.name).title()

class Person(object ):

   def __init__(self,name,aliasname=None):

          self.aliasname=aliasname

   aliasname=DefaultAlias('name')

>> > p=Person('sam')

>>>> p.aliasname
'Sam'
>>>>> p.aliasname='jack'
>>> > p.aliasname
'jack'
>>>>> del p.aliasname
>>> p.aliasname
'Sam'


這樣就為屬性name設定了一個別名aliasname,或者說把aliasname的值儲存在了name中。 DefaultAlias不是資料結構,因為它沒有__set__方法,但是一個非資料介面。所以我們給一個實例屬性屬性時(p.aliasname='jack'),實例會正常記錄屬性,並且實例屬性會覆寫掉類別屬性。這樣aliasname屬性就可以單獨的設定而不影響name屬性了。當我們del p.aliasname時,刪除了的屬性,類別屬性又會重新出現。

某些對於開發的類,如果要保持後續版本的兼容性,可以用新名稱來命名方法和屬性,同時保留舊名稱的可用性。

class OldAlias(object):
   def __init__(self,name,oldname):
       self.name=name
     self..oldname=W print 'use %r,not %r'%( self.name,self.oldname)
   def __get__(self,instance,own):
       self._warn()
           return getattr(instance,self.name)
   def __set__(self, instance,value):
       self._warn()
       setattr(instance,self.name,value)
    delattr(instance,self.name)
class NewClass( object):
   def __init__(self,newname):
       self.newname=newname
   oldname=OldAlias('newname','oldname')
   oldname=OldAlias('newname','oldname')
> coldname=OldAlias('newname','oldname')
> cold")
>.
use 'newname',not 'oldname'
'a'


使用這個類別的舊程式碼會使用類別屬性oldname,同時一個警告訊息被列印,鼓勵使用者使用新屬性newname。

快取屬性值

根據需求計算實例屬性或類別屬性的值,並提供自動化的快取。

class CachedAttribute(object):

   def __init__(self,method,name=None):

       self.method=method __get__(self,instance,own):

       if instance is None:

           return self
       result=self.method(instance)🠎) .   return result
class MyObject(object):
   def __init__(self,n):
       self .n=n
   @CachedAttribute
   def square(self):
       return self.n*self.n
>>> m=MyObject(2). >>> m.square
4
>>> del m.square
>>> m.square
25


在首次存取m.square後,square屬性就被快取在實例m中,當改變實例屬性n時,square屬性不會改變。如果需要清除緩存,del m.square即可,再次存取m.square屬性square的值會再次計算。

快取類別屬性:

class CachedClassAttribute(CachedAttribute):
   def __get__(self,instance,own):
    __AtTClass:returns
   class_attr= 24
   @CachedClassAttribute
   def square(cls):
       return cls.class_attr*cls.class_attr

> > b=MyClass()

>>> a.square

>>> print a.square

576

>>> print b.square
576
>>> print MyClass.square
576
descriptor(二)的內容,更多相關內容請關注PHP中文網(www.php.cn)!



陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn