1、python中建立類屬性
類是模板,而例項則是根據類建立的物件。
繫結在乙個例項上的屬性不會影響其他例項,但是,類本身也是乙個物件,如果在類上繫結乙個屬性,則所有例項都可以訪問類的屬性,並且,所有例項訪問的類屬性都是同乙個!也就是說,例項屬性每個例項各自擁有,互相獨立,而類屬性有且只有乙份。
定義類屬性可以直接在 class 中定義:
classperson(object):
address = '
earth
'def
__init__
(self, name):
self.name = name
因為類屬性是直接繫結在類上的,所以,訪問類屬性不需要建立例項,就可以直接訪問:
person.address
#=> earth
對乙個例項呼叫類的屬性也是可以訪問的,所有例項都可以訪問到它所屬的類的屬性:
p1 = person('bob'
)p2 = person('
alice')
p1.address
#=> earth
p2.address
#=> earth
由於python是動態語言,類屬性也是可以動態新增和修改的:
person.address = 'china
p1.address
#=> 'china'
p2.address
#=> 'china'
因為類屬性只有乙份,所以,當person類的address改變時,所有例項訪問到的類屬性都改變了。
2、python中類屬性和例項屬性名字衝突怎麼辦
修改類屬性會導致所有例項訪問到的類屬性全部都受影響,但是,如果在例項變數上修改類屬性會發生什麼問題呢?
classperson(object):
address = '
earth
'def
__init__
(self, name):
self.name =name
p1 = person('
bob'
)p2 = person('
alice')
'person.address =
' +person.address
p1.address = '
china
'p1.address =
' +p1.address
'person.address =
' +person.address
'p2.address =
' + p2.address
結果如下:
person.address =earthp1.address =china
person.address =earth
p2.address = earth
我們發現,在設定了 p1.address = 'china' 後,p1訪問 address 確實變成了 'china',但是,person.address和p2.address仍然是'earch',怎麼回事?
原因是 p1.address = 'china'並沒有改變 person 的 address,而是給 p1這個例項繫結了例項屬性address ,對p1來說,它有乙個例項屬性address(值是'china'),而它所屬的類person也有乙個類屬性address,所以:
訪問 p1.address 時,優先查詢例項屬性,返回'china'。
訪問 p2.address 時,p2沒有例項屬性address,但是有類屬性address,因此返回'earth'。
可見,當例項屬性和類屬性重名時,例項屬性優先順序高,它將遮蔽掉對類屬性的訪問。
當我們把 p1 的 address 例項屬性刪除後,訪問 p1.address 就又返回類屬性的值 'earth'了:
delp1.address
p1.address
#=> earth
可見,千萬不要在例項上修改類屬性,它實際上並沒有修改類屬性,而是給例項繫結了乙個例項屬性。
3、python中定義例項方法
乙個例項的私有屬性就是以__開頭的屬性,無法被外部訪問,那這些屬性定義有什麼用?
雖然私有屬性無法從外部訪問,但是,從類的內部是可以訪問的。除了可以定義例項的屬性外,還可以定義例項的方法。
例項的方法就是在類中定義的函式,它的第乙個引數永遠是 self,指向呼叫該方法的例項本身,其他引數和乙個普通函式是完全一樣的:
classperson(object):
def__init__
(self, name):
self.
__name =name
defget_name(self):
return self.__name
get_name(self) 就是乙個例項方法,它的第乙個引數是self。__init__(self, name)其實也可看做是乙個特殊的例項方法。
呼叫例項方法必須在例項上呼叫:
p1 = person('bob'
)print p1.get_name() #
self不需要顯式傳入
#=> bob
在例項方法內部,可以訪問所有例項屬性,這樣,如果外部需要訪問私有屬性,可以通過方法呼叫獲得,這種資料封裝的形式除了能保護內部資料一致性外,還可以簡化外部呼叫的難度.
練習:
請給 person 類增加乙個私有屬性 __score,表示分數,再增加乙個例項方法 get_grade(),能根據 __score 的值分別返回 a-優秀, b-及格, c-不及格三檔。
#-*- coding:utf-8-*-
class
person(object):
def__init__
(self, name, score):
self.
__name=name
self.
__score=score
defget_grade(self):
if self.__score>=80:
return
"a-優秀
"elif self.__score>=60:
return
"b-及格
"return
"c-不及格
"p1 = person('
bob', 90)
p2 = person('
alice
', 65)
p3 = person('
tim', 48)
p1.get_grade()
p2.get_grade()
print p3.get_grade()
4、python中方法也是屬性
我們在 class 中定義的例項方法其實也是屬性,它實際上是乙個函式物件:
classperson(object):
def__init__
(self, name, score):
self.name =name
self.score =score
defget_grade(self):
return'a
'p1 = person('
bob', 90)
p1.get_grade
#=> >
p1.get_grade()
#=> a
也就是說,p1.get_grade 返回的是乙個函式物件,但這個函式是乙個繫結到例項的函式,p1.get_grade() 才是方法呼叫。
因為方法也是乙個屬性,所以,它也可以動態地新增到例項上,只是需要用 types.methodtype() 把乙個函式變為乙個方法:
importtypes
deffn_get_grade(self):
if self.score >= 80:
return'a
'if self.score >= 60:
return'b
'return'c
'class
person(object):
def__init__
(self, name, score):
self.name =name
self.score =score
p1 = person('
bob', 90)
p1.get_grade =types.methodtype(fn_get_grade, p1, person)
p1.get_grade()
#=> a
p2 = person('
alice
', 65)
p2.get_grade()
#error: attributeerror: 'person' object has no attribute 'get_grade'
# 因為p2例項並沒有繫結get_grade給乙個例項動態新增方法並不常見,直接在class中定義要更直觀。
python物件導向學習 python物件導向學習
物件導向最重要的概念就是類 class 和例項 instance 必須牢記類是抽象的模板,比如student類,而例項是根據類建立出來的乙個個具體的 物件 每個物件都擁有相同的方法,但各自的資料可能不同。物件導向三個概念 1.封裝 即把客觀事物封裝成抽象的類,並且類可以把自己的資料和方法讓可信的類進...
python物件導向總結 Python物件導向總結
python 物件導向 oop 1 物件導向 是乙個更大封裝,把乙個物件封裝多個方法 2 類 是對一些具有相同特徵或行為的事物的乙個統稱,是抽象的,不能直接使用 特徵被稱為屬性 行為被稱為方法 3 物件 是由類建立出來的乙個具體的存在,可以直接使用 先有類再有物件,類只有乙個,而物件可以有多個 類中...
python登入物件導向 python 物件導向
一 屬性和方法 1.a a 例項屬性 通過例項物件來新增的屬性就是例項屬性 a.count 10 例項方法都是在類中直接定義的 以self為第乙個引數的方法都是例項方法 當通過例項物件呼叫時,會自動傳遞當前物件作為self傳入 當通過類物件呼叫時,不會自動傳遞self a.test 等價於 a.te...