在Python中想定義一個類是比較簡單的,好比要定義一個Person類,以下代碼便可:微信
# -*- coding: utf-8 -*- # __author : Demon # date : 1/5/18 8:24 PM class Person(object): pass p1 = Person()
固然咱們也能夠給類添加相應的屬性,好比Person的姓名,年齡,性別等,而且在new一個Person對象後能夠對這些屬性進行修改,以下代碼所示:spa
# -*- coding: utf-8 -*- # __author : Demon # date : 1/5/18 8:24 PM class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.age = age #年齡 self.sex = sex #性別 def __str__(self): #定義直接打印Person對象,輸出的內容。至關於Java中的toString()方法 return ('%s , %s , %s ' % (self.name, self.age, self.sex)) p1 = Person('Demon', 18, 'M') print(p1) #Demon , 18 , M p1.age = 28 #修改對象的年齡 print(p1) #Demon , 28 , M
Python是面向對象的語言,咱們都知道面向對象的三大特色:繼承、封裝和多態。而在上面的代碼中,咱們能夠輕易地經過person. 調用屬性來訪問和修改值,這明顯不符合面向對象中封裝的思想。好比對於Person類中的年齡屬性,可能比較私人,因此咱們不但願能夠任意的訪問和修改它的值。在Java中,咱們是經過private關鍵字來裝飾屬性私有,那麼在Python中有沒有相似的關鍵字呢?顯然是有的,在Python中採起在變量名前加__(兩個下劃線)的方式來將屬性私有。以下代碼所示:對象
# -*- coding: utf-8 -*- # __author : Demon # date : 1/5/18 8:24 PM class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年齡,將年齡私有 self.sex = sex #性別 def __str__(self): #定義直接打印Person對象,輸出的內容。至關於Java中的toString()方法 return ('%s , %s , %s ' % (self.name, self.__age, self.sex)) p1 = Person('Demon', 18, 'M') print(p1) #Demon , 18 , M p1.age = 28 #這裏只是給p1對象動態的增長了一個age屬性 print(p1) #Demon , 18 , M print(p1.age) #28
初看上面的代碼,彷佛感受並無達到私有的目的,由於咱們經過p1.age仍是成功地進行了賦值,程序並無報錯。其實這裏是由於Python能夠動態地給對象增長屬性和方法,這句話至關於動態地給p1這個對象增長了一個age屬性。因此在咱們作了賦值操做以後,咱們再次打印p1,age的值依然是18。說明咱們確實已經將類裏的age屬性進行的私有。同理方法的私有也是同樣的處理。繼承
在Python中,有幾種方式來定義變量:utf-8
一、以單劃線開頭:這種類型的變量能夠經過對象.調用,可是它表示的意思是我能夠調用,但請把我視爲是私有的。並且若是是經過from xxx_module import *是沒法訪問的,可是若是是import xxx_module的方式,則能夠訪問到,類對象和子類也均可以訪問。get
二、僅以雙劃線開頭:這種類型的變量就是私有。可是它能夠經過__類名__變量名來訪問,但強烈建議不要這樣作it
三、以雙劃線開頭,並以它結尾:這種類型的變量在Python中一般都表示具備特殊意義的變量,好比__init__,__str__等。因此咱們在定義變量時不要這樣定義class
四、僅以單劃線結尾:這種類型的變量是用於避免與Python關鍵字進行衝突所採起的一種解決辦法import
以下圖演示訪問權限效果:變量
上面的介紹了,經過加雙劃線開頭的方式實現了變量和方法。參照在學Java時的思路,若是想要訪問私有變量,咱們會給變量添加get和set方法。一樣咱們在Python中也是同樣的處理,代碼以下所示:
class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年齡,將年齡私有 self.sex = sex #性別 def getAge(self): return self.__age def setAge(self, age): self.__age = age p1 = Person('Demon', 18, 'M') print(p1.getAge()) #18 p1.setAge(28) print(p1.getAge()) #28
可是這樣看着彷佛不是很方便,每次都要調用一個方法。有沒有可能像以前同樣調用p1. age = 28就能直接賦值呢?顯然在Python中是能夠的,這就要用到property。
property的定義:
使用代碼示例:
class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年齡,將年齡私有 self.sex = sex #性別 def getAge(self): return self.__age def setAge(self, age): self.__age = age age = property(getAge, setAge, 'This is age property') p1 = Person('Demon', 18, 'M') print(p1.age) #18 p1.age = 28 print(p1.age) #28
說明:
1. property接受四個參數,分別是get, set, del, doc,前三個參數分別對應get方法,set方法,del方法,順序不能出錯。最後一個參數是doc,至關於對方法進行說明。
2. property返回一個property屬性,返回值的變量名與最終對象. 後面的名稱是一致的
觀察上面的代碼,咱們仍然須要多寫一行property的代碼,而Python其實提供了一個更方便的實現方式來達到上述要求,即便用@property。說明以下:
示例代碼以下:
class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年齡,將年齡私有 self.sex = sex #性別 @property def age(self): #注意方法名直接爲變量名 return self.__age @age.setter #注意方法名直接爲變量名 def age(self, age): self.__age = age p1 = Person('Demon', 18, 'M') print(p1.age) #18 p1.age = 28 print(p1.age) #28
說明:
1. @property至關於對age方法進行了一個裝飾,它使得咱們能經過對象.方法名來調用對應的屬性
2. @property所裝飾的方法名與對象 . 調用的名稱要保持一致
3. @property會生成另外的裝飾器,@方法名.setter, @方法名.getter, @方法名.deleter,分別對應set, get, del方法。這裏get方法用得不多,由於已經經過@property直接對應到了get方法
微信搜索【帕森與加瓦】可關注公衆號