接上一文
- 偽私有目的:
防止外界直接訪問
防止被子類同名稱屬性覆蓋 - 為什么叫偽私有拧揽?
print(Animal.__x)訪問不到
但是——print(Animal._Animal__x)可以訪問到 - 但還是不建議這么去訪問私有屬性
只讀屬性
- 只能讀取止邮,不能寫入勃救,一般是實(shí)例屬性
設(shè)置方法一
- 內(nèi)置方法去讀取
class Person:
def __init__(self):
self.__age=18 #不能訪問了
def getAge(self):
return self.__age #這樣就可以讀取
p1=Person()
print(p1.__age) #不行 報(bào)錯(cuò)
print(p1.getAge()) #可以
設(shè)置方法二
class Person:
def __init__(self):
self.__age=18 #不能訪問了
#作用:可以以使用屬性讀取的方式來使用這個(gè)方法
@property
def getAge(self):
return self.__age #這樣就可以讀取
p1=Person()
print(p1.age) #可以
p1.age=666 #不可以
對于property的理解
以讀取屬性的方式用方法
可以將一些屬性的操作(刪、改、查)關(guān)聯(lián)到屬性中
補(bǔ)充概念
經(jīng)典類:沒有繼承object(類)
新式類:繼承object
在python3里面直接定義一類涂召,直接默認(rèn)定義的是新式類麻捻,繼承object
在新式類的使用方式
class Person(object):
def __init__(self):
self.__age=18
def get_age(self):
return self.__age
def set_age(self,value):
self.__age=value
age=property(get_age, set_age)
p=Person()
print(p.age) #可以獲取age,18
p.age=90
print(p.age) #90
第二種使用方式
class Person(object):
def __init__(self):
self.__age=18
@property
def age(self):
return self.__age
@age.setter
def age(self,value):
self.__age=value
p=Person()
print(p.age) #18
p.age=10
print(p.age) #10
在經(jīng)典類中的使用方式
- 首先要將版本換成python2兼蕊,否則定義類之后默認(rèn)繼承object初厚,即是新式類,沒法定義成經(jīng)典類
class Person:
def __init__(self):
self.__age=18
def get_age(self):
return self.__age
def set_age(self,value):
self.__age=value
age=property(get_age, set_age)
p=Person()
print(p.age) #18
p.age=19
print(p.age) #19
#但是這個(gè)值為19的age是一個(gè)新的變量,不是原來的類里面的__age的值改為了19
- 裝飾器的方式
class Person:
def __init__(self):
self.__age=18
@property
def age(self):
print '---get'
return self.__age
@age.setter
def age(self,value):
self.__age=value
p=Person()
print p.age #---get 18
p.age=19
print p.age #19
print p.__dict__ #{'age':19,'_Person__age':18}
- 這里要告訴我們的是:
在經(jīng)典類里面設(shè)置age值是可以做的产禾,但是這樣做的并不是對__age值的改變排作,只是添加了多一個(gè)值age - 切記這一現(xiàn)象
- 建議以后都使用新式類
用系統(tǒng)內(nèi)置的方法設(shè)置只讀屬性
- 剛剛提到的方式設(shè)置只讀屬性還是有漏洞,因?yàn)槠鋵?shí)還是有辦法可以修改只讀屬性
p1._Person__age = 999
p1.__dict__['_Person__age']=999
- 因此我們提出:__setattr__的使用
class Person:
#當(dāng)我們通過實(shí)例.屬性 =值亚情,給一個(gè)實(shí)例增加一個(gè)屬性妄痪,或者說,修改一下屬性值的時(shí)候楞件,都會(huì)調(diào)用這個(gè)方法
#在這個(gè)方法內(nèi)部衫生,才會(huì)真正把這個(gè)屬性以及對應(yīng)的值給存儲(chǔ)到__dict__字典里面
def __setattr__(self, key, value):
print(key, value)
p1=Person()
p1.age=18 # age 18
print(p1.age) #報(bào)錯(cuò)
print(p1.__dict__) #{}
- 這里告訴我們實(shí)例p1并沒有獲得age屬性
class Person:
#當(dāng)我們通過實(shí)例.屬性 =值,給一個(gè)實(shí)例增加一個(gè)屬性土浸,或者說罪针,修改一下屬性值的時(shí)候泪酱,都會(huì)調(diào)用這個(gè)方法
#在這個(gè)方法內(nèi)部,才會(huì)真正把這個(gè)屬性以及對應(yīng)的值給存儲(chǔ)到__dict__字典里面
def __setattr__(self, key, value):
print(key, value)
#1.判定还最,key墓阀,是否是我們要設(shè)置的只讀屬性的名稱
if key=='age':
print('這個(gè)屬性是只讀屬性,不能設(shè)置數(shù)據(jù)')
#2 .如果不是拓轻,只讀屬性的名次斯撮,真正的給它添加到這個(gè)實(shí)例里面去
else:
self.__dict__[key]=value
p1=Person() # age 18
p1.age=18 # 這個(gè)屬性是只讀屬性,不能設(shè)置數(shù)據(jù)
print(p1.__dict__) #{}
p1.name='sz' # name sz
print(p1.__dict__) #{'name':'sz'}
- 可以添加屬性name扶叉,不能添加屬性age
- 下面再在if條件里多加一個(gè)and條件
- 添加這條條件之后在第一次添加屬性age的時(shí)候可以添加
- 但后來不能在修改了吮成,是只讀屬性
class Person:
#當(dāng)我們通過實(shí)例.屬性 =值,給一個(gè)實(shí)例增加一個(gè)屬性辜梳,或者說粱甫,修改一下屬性值的時(shí)候,都會(huì)調(diào)用這個(gè)方法
#在這個(gè)方法內(nèi)部作瞄,才會(huì)真正把這個(gè)屬性以及對應(yīng)的值給存儲(chǔ)到__dict__字典里面
def __setattr__(self, key, value):
print(key, value)
#1.判定茶宵,key,是否是我們要設(shè)置的只讀屬性的名稱
if key=='age' and key in self.__dict__.keys():
print('這個(gè)屬性是只讀屬性宗挥,不能設(shè)置數(shù)據(jù)')
#2 .如果不是乌庶,只讀屬性的名次,真正的給它添加到這個(gè)實(shí)例里面去
else:
self.__dict__[key]=value
p1=Person() # age 18
p1.age=18 # 18
print(p1.__dict__) #{'age':18}
p1.age=999# age 999
#這個(gè)屬性只是只讀屬性契耿,不能設(shè)置數(shù)據(jù)
p1.age=18 # 18
print(p1.__dict__) #{'age':18}
系統(tǒng)內(nèi)置的特殊屬性
- 創(chuàng)建好類之后自動(dòng)就有的一些屬性
- __dict__:類的屬性
__bases__:類的所有父類構(gòu)成元組
__doc__:類的文檔字符串
__name__:類名
__model__:類定義所在的模塊
一瞒大、類屬性
class Person:
"""
這是一個(gè)人,類
"""
age =19
def __init__(self):
self.name='sz'
def run(self):
print('run')
print(Person.__dict__) #輸出好多東西的字典搪桂,有__model__透敌,有age盯滚,有run等等
print(Person.__bases__) # (<class 'object'>,)
print(Person.__doc__) #這是一個(gè)人,類
print(Person.__name__) # Person
pritn(Person.__module__) #__main__
二酗电、實(shí)例屬性
- __class__
class Person:
"""
這是一個(gè)人魄藕,類
"""
age =19
def __init__(self):
self.name='sz'
def run(self):
print('run')
p=Person()
print(p.__class__) #<class '__main__>Person'>