面向對象進階
1. 訪問權限
1.1 @property
前面講到方法里咕痛,python 可以通過下劃線來標識方法和屬性的權限读第,
name
公共,__name
私有,_name
保護
那么如果想訪問屬性可以通過屬性的getter(訪問器)和setter(修改器)方法進行對應的操作。如果要做到這點,就可以考慮使用@property包裝器來包裝getter和setter方法猜扮,使得對屬性的訪問既安全又方便,代碼如下所示监婶。
class safe:
__test = 100
def __init__(self,test):
self.__test = test
@property
def test(self):
return self.__test
@test.getter
def test(self):
return self.__test
@test.setter
def test(self,test):
self.__test = test
def show(self):
print('self.__test:', self.__test)
a = safe(1000)
a.show()
print(a.test)
print(a.test)
a.test = 1111
a.show()
try:
print(a.__test)
except AttributeError as err1:
print(err1)
結果:
self.__test: 1000
1000
1000
self.__test: 1111
'safe' object has no attribute '__test'
1.2 __slots__
前面說到屬性是可以動態(tài)刪減的旅赢,如果想保護起來,就得用
__slots__
保護起來
這個關鍵字聲明了只有它限定得屬性是可讀可寫的惑惶,不再元組里的只能讀煮盼,不能寫
看例子:
class test_private:
'nothong'
__slots__ = ('_name', '_age', '_high')
test = 111
def __init__(self,name,age,high):
self._name = name
self._age = age
self._high = high
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter
def age(self, age):
self._age = age
def play(self):
if self._age <= 16:
print('%s正在玩飛行棋.' % self._name)
else:
print('%s正在玩斗地主.' % self._name)
a = test_private('zhangsan', 18, 130)
a.play()
try:
print('a.name : ', a.name)
except AttributeError as err1:
print('err1: ',err1)
try:
a.ability = 'aaa'
except AttributeError as err2:
print('err2:',err2)
try:
a.test = 1000
print(a.test)
except AttributeError as err3:
print('err3', err3)
a.age = 15
a.play()
結果:
zhangsan正在玩斗地主.
a.name : zhangsan
err2: 'test_private' object has no attribute 'ability'
err3 'test_private' object attribute 'test' is read-only
zhangsan正在玩飛行棋.
2. 靜態(tài)方法和類方法
之前,我們在類中定義的方法都是對象方法带污,也就是說這些方法都是發(fā)送給對象的消息僵控。靜態(tài)方法是可以發(fā)消息給類的,就是說刮刑,類和對象都可以執(zhí)行喉祭,代碼如下所示养渴。
class test_static:
@staticmethod
def test_static(cls):
print('you can do')
@staticmethod
def test_no_param():
print('you cant')
cls = ''
test_static.test_static(cls=cls)
test_static.test_no_param()
a = test_static()
a.test_static(cls=cls)
a.test_no_param()
結果:
you can do
you cant
you can do
you cant
可以不用加cls
和靜態(tài)方法比較類似,Python還可以在類中定義類方法泛烙,類方法的第一個參數(shù)約定名為cls理卑,它代表的是當前類相關的信息的對象(類本身也是一個對象,有的地方也稱之為類的元數(shù)據(jù)對象)蔽氨,通過這個參數(shù)我們可以獲取和類相關的信息并且可以創(chuàng)建出類的對象藐唠,隨便給自己初始化了,但是要通過靜態(tài)方法鹉究,返回的也是個cls宇立,就是自己,代碼如下所示自赔。
import os
from time import time, localtime, sleep
class Clock(object):
"""數(shù)字時鐘"""
def __init__(self, hour=0, minute=0, second=0):
self._hour = hour
self._minute = minute
self._second = second
@classmethod
def now(cls):
ctime = localtime(time())
return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)
def run(self):
"""走字"""
self._second += 1
if self._second == 60:
self._second = 0
self._minute += 1
if self._minute == 60:
self._minute = 0
self._hour += 1
if self._hour == 24:
self._hour = 0
def show(self):
"""顯示時間"""
return '%02d:%02d:%02d' % \
(self._hour, self._minute, self._second)
結果:
18:56:04
就是個1s一次的時間
3. 類之間的關系
這個完全用作者的了妈嘹,主要是要理解
簡單的說,類和類之間的關系有三種:is-a绍妨、has-a和use-a關系润脸。
- is-a關系也叫繼承或泛化,比如學生和人的關系他去、手機和電子產品的關系都屬于繼承關系毙驯。
- has-a關系通常稱之為關聯(lián),比如部門和員工的關系灾测,汽車和引擎的關系都屬于關聯(lián)關系爆价;關聯(lián)關系如果是整體和部分的關聯(lián),那么我們稱之為聚合關系媳搪;如果整體進一步負責了部分的生命周期(整體和部分是不可分割的铭段,同時同在也同時消亡),那么這種就是最強的關聯(lián)關系蛾号,我們稱之為合成關系稠项。
- use-a關系通常稱之為依賴,比如司機有一個駕駛的行為(方法)鲜结,其中(的參數(shù))使用到了汽車展运,那么司機和汽車的關系就是依賴關系。
uml-components.png
uml-example.png
直接上大神的圖
利用類之間的這些關系精刷,我們可以在已有類的基礎上來完成某些操作拗胜,也可以在已有類的基礎上創(chuàng)建新的類,這些都是實現(xiàn)代碼復用的重要手段怒允。復用現(xiàn)有的代碼不僅可以減少開發(fā)的工作量埂软,也有利于代碼的管理和維護,這是我們在日常工作中都會使用到的技術手段。
方便開發(fā)勘畔,幫助你我他
4. 繼承和多態(tài)
繼承和多繼承在上一個文章已經講了
面向對象三大法寶所灸,封裝,繼承炫七,多態(tài)爬立,
- 封裝:就是類的作用
- 繼承:就是通過繼承基類已經實現(xiàn)的方法和屬性,來減少開發(fā)量万哪,方便你我他
- 多態(tài) :就是在繼承的基礎上可以對基類的方法的重寫侠驯,讓子類和父類的方法表現(xiàn)形式不一樣
可能表述有些問題,但是基本方向沒啥問題
文集傳送門 學習python100天
整個學習python100天的目錄傳送門
無敵分割線
再最后面附上大神的鏈接 傳送門