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()
def __init__(self,name,aliasname=None):
self.aliasname=aliasnamealiasname=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)!