訪問可見性
很多物件導向程式設計語言中,通常會將物件的屬性設定為私有的(private)或受保護的(protected),簡單的說就是不允許外界訪問,而物件的方法通常都是公開的(public),因為公開的方法就是物件能夠接受的訊息。
在python中,屬性和方法的訪問許可權只有兩種,也就是公開的和私有的,如果希望屬性是私有的,在給屬性命名時可以用兩個下劃線作為開頭:
class
test
(object):
def__init__
(self, foo)
: self.__foo = foo
def__bar
(self)
:print
(self.__foo)
print
('__bar'
)def
main()
: test = test(
'hello'
) test.__bar(
)# attributeerror: 'test' object has no attribute '__bar'
print
(test.__foo)
# attributeerror: 'test' object has no attribute '__foo'
if __name__ ==
"__main__"
: main(
)
然而實際上並沒有任何辦法讓python的類屬性和方法完全私有,我們仍可以從外界這樣呼叫:
test = test(
'hello'
)test._test__bar(
)print
(test._test__foo)
其實兩個下劃線開頭的變數只是讓原變數名字變了,來「妨礙」我們呼叫它。但實際開發中,並不建議將屬性設定為私有的,因為這會導致子類無法訪問。因此約定俗成的變數屬性寫法是單下劃線加變數名(_xx),這並不是語法規則,也不能阻止外部**呼叫它,只是告訴你這是個類屬性,請不要從外部直接呼叫,「防君子不防小人」。
@property裝飾器
如果外部想直接訪問類的屬性,但同時又不建議直接訪問,辦法是使用裝飾器將類方法「偽裝」成屬性,通過屬性的getter(訪問器)和setter(修改器)方法進行對應的操作,既方便又安全。
class
person
(object):
def__init__
(self, name, age)
: self._name = name
self._age = age
# 訪問器 - getter方法
@property
defname
(self)
:return self._name
# 修改器 - setter方法
@name.setter
defname
(self, name)
: self._name = name
# 訪問器 - getter方法
@property
defage
(self)
:return self._age
# 修改器 - setter方法
@age.setter
defage(self, age)
: self._age = age
defmain()
: p = person(
'小明',12
)print
(p.name)
p.name =
'大明'
print
(p.name)
print
(p.age)
p.age =
16print
(p.age)
if __name__ ==
'__main__'
: main(
)
注意訪問器和修改器下定義的類方法名稱要一致。
靜態方法和類方法
靜態方法無需將類例項化,直接在類之後使用。最常見的使用場景是校驗類傳入值是否符合要求,比如例項化三角形前判斷傳入的三條邊長是否能構成三角形:
class
********
(object):
def__init__
(self, a, b, c)
: self._a = a
self._b = b
self._c = c
@staticmethod
#靜態方法裝飾器
defis_valid
(a, b, c)
:# 無需傳入表示例項引數self,也無需傳入表示類引數cls
return a + b > c and b + c > a and a + c > b
defmain()
:if ********.is_valid(3,
4,5)
:# 呼叫靜態方法前面需要跟上類名稱
t = ********(3,
4,5)
if __name__ ==
'__main__'
: main(
)
和靜態方法比較類似,python還可以在類中定義類方法,類方法的第乙個引數約定名為cls,它代表的是當前類相關的資訊的物件(類本身也是乙個物件,有的地方也稱之為類的元資料物件),通過這個引數我們可以獲取和類相關的資訊並且可以建立出類的物件:
class
********
(object):
def__init__
(self, a, b, c)
: self._a = a
self._b = b
self._c = c
@staticmethod
#靜態方法裝飾器
defis_valid
(a, b, c)
:# 無需傳入表示例項引數self,也無需傳入表示類引數cls
return a + b > c and b + c > a and a + c > b
@classmethod
defcreate_********
(cls, a, b, c)
:if cls.is_valid(a, b, c)
:return cls(a, b, c)
else
:return
'無法構成三角形'
defmain()
: t = ********.create_********(3,
4,5)
if __name__ ==
'__main__'
: main(
)
該例中類方法呼叫了靜態方法,當條件滿足時,建立類的例項;不滿足時輸出提示資訊。注意類方法用來被類直接呼叫,但例項也可以呼叫類方法,同理對於靜態方法類和例項都可以呼叫。 C 學習雜記之 物件導向
1 物件是類的乙個例項 instance 重要的是類的設計而不是物件的設計,類要注重行為的設計而不是資料 的設計,所以類中先public 成員函式。2 繼承與程式復用性的關係 1 b繼承a,則b必須是a的一種 如果b是a的一部分,則不允許b繼承a的功能 2 通過繼承,實現了後來寫的程式可以使用以前寫...
C 學習雜記之 物件導向
1 物件是類的乙個例項 instance 重要的是類的設計而不是物件的設計,類要注重行為的設計而不是資料 的設計,所以類中先public 成員函式。2 繼承與程式復用性的關係 1 b繼承a,則b必須是a的一種 如果b是a的一部分,則不允許b繼承a的功能 2 通過繼承,實現了後來寫的程式可以使用以前寫...
python 物件導向(一)
def 函式名 x 定義乙個類的方式為 class 類名 xx 定義乙個貓類 class cat 屬性 方法 defeat self print s吃 s 5,5 defplay self print 玩 xiaohuamao cat eat 列印結果 吃 獲取物件屬性 定義乙個貓類 class c...