1. 程式人生 > >python使用@property @x.setter @x.deleter

python使用@property @x.setter @x.deleter

@property可以將python定義的函式“當做”屬性訪問,從而提供更加友好訪問方式,但是有時候setter/deleter也是需要的。
1》只有@property表示只讀
2》同時有@property和@x.setter表示可讀可寫

3》同時有@property和@x.setter和@x.deleter表示可讀可寫可刪除

class student(object):  #新式類
    def __init__(self,id):  
        self.__id=id  
    @property  #讀  
    def score(self):  
        return self._score  
    @score.setter #寫  
    def score(self,value):  
        if not isinstance(value,int):  
            raise ValueError('score must be an integer!')    
        if value<0 or value>100:  
            raise ValueError('score must between 0 and 100')   
        self._score=value  
    @property #讀(只能讀,不能寫)  
    def get_id(self):  
        return self.__id  
  
s=student('123456')  
s.score=60 #寫  
print s.score #讀  
#s.score=-2 #ValueError: score must between 0 and 100  
#s.score=32.6 #ValueError: score must be an integer!  
s.score=100 #寫  
print s.score #讀  
print s.get_id #讀(只能讀,不可寫)
#s.get_id=456 #只能讀,不可寫:AttributeError: can't set attribute

執行結果:
60
100
123456

class A(object):#新式類(繼承自object類)
    def __init__(self):
        self.__name=None
    def getName(self):
        return self.__name
    def setName(self,value):
        self.__name=value
    def delName(self):
        del self.__name
    name=property(getName,setName,delName)

a=A()
print a.name #讀
a.name='python' #寫
print a.name #讀
del a.name #刪除
#print a.name #a.name已經被刪除 AttributeError: 'A' object has no attribute '_A__name'
執行結果:
None
python
class A(object):#要求繼承object
    def __init__(self):
        self.__name=None
    
    #下面開始定義屬性,3個函式的名字要一樣!
    @property #讀
    def name(self):
        return self.__name
    @name.setter #寫
    def name(self,value):
        self.__name=value
    @name.deleter #刪除
    def name(self):
        del self.__name
    
a=A()
print a.name #讀
a.name='python'  #寫
print a.name #讀
del a.name #刪除
#print a.name # a.name已經被刪除 AttributeError: 'A' object has no attribute '_A__name'  
執行結果:
None
python
class person(object):
    def __init__(self,first_name,last_name):
        self.first_name=first_name
        self.last_name=last_name
    @property #讀
    def full_name(self):
        return '%s %s' % (self.first_name,self.last_name) 

p=person('wu','song')
print p.full_name #讀
#p.full_name='song ming' #只讀,不可修改  AttributeError: can't set attribute  
p.first_name='zhang'
print p.full_name #讀
執行結果:
wu song
zhang song
上面都是以新式類為例子,下面我們看一個包含經典類的例子:
#!/usr/bin/env python
#coding:utf-8

class test1:#經典類:沒有繼承object    
    def __init__(self):    
        self.__private='alex 1' #私有屬性以2個下劃線開頭    
    #讀私有屬性    
    @property    
    def private(self):    
        return self.__private    
    #嘗試去寫私有屬性(對於經典類而言,“寫”是做不到的,注意看後邊的程式碼和註釋!)  
    @private.setter    
    def private(self,value):    
        self.__private=value   
    #嘗試去刪除私有屬性(對於經典類而言,“刪除”也是做不到的,具體看後邊的程式碼和註釋!)  
    @private.deleter  
    def private(self):  
        del self.__private  
      
class test2(object):#新式類:繼承了object    
    def __init__(self):    
        self.__private='alex 2' #私有屬性以2個下劃線開頭    
    #讀私有屬性    
    @property    
    def private(self):    
        return self.__private    
    #寫私有屬性    
    @private.setter    
    def private(self,value):    
        self.__private=value  
    #刪除私有屬性  
    @private.deleter  
    def private(self):  
        del self.__private  
      
t1=test1()    
#print t1.__private #外界不可直接訪問私有屬性    
print t1.private #讀私有屬性
print t1.__dict__   
t1.private='change 1' #對於經典類來說,該語句實際上是為例項t1添加了一個例項變數private  
print t1.__dict__  
print t1.private #輸出剛剛新增的例項變數private  
t1.private='change 2'  
print t1.__dict__  
del t1.private #刪除剛剛新增的例項變數private  
print t1.__dict__  
print t1.private #讀私有屬性
#del t1.private #無法通過這種方式刪除私有屬性:AttributeError: test1 instance has no attribute 'private'
#對於經典類而言,我們無法通過上面的語句,對例項的私有變數__private進行修改或刪除!  
print '-------------------------------------------------------'    
t2=test2()    
print t2.__dict__  
print t2.private #繼承了object,新增@private.setter後,才可以寫    
t2.private='change 2' #修改私有屬性    
print t2.__dict__   
print t2.private  
del t2.private #刪除私有變數  
#print t2.private #私有變數已經被刪除,執行“讀”操作會報錯:AttributeError: 'test2' object has no attribute '_test2__private'    
print t2.__dict__  
#對於新式類而言,我們可以通過上面的語句,對例項的私有變數__private進行修改或刪除  
執行結果:

alex 1
{'_test1__private': 'alex 1'}
{'_test1__private': 'alex 1', 'private': 'change 1'}
change 1
{'_test1__private': 'alex 1', 'private': 'change 2'}
{'_test1__private': 'alex 1'}
alex 1
-------------------------------------------------------
{'_test2__private': 'alex 2'}
alex 2
{'_test2__private': 'change 2'}
change 2
{}

(完)