上海網(wǎng)站建設(shè)百家號廣告投放推廣平臺
再談抽象
對象
- 多態(tài) 即便你不知道變量指向的是哪種對象,也能夠?qū)ζ鋱?zhí)行操作
- 封裝 向外部隱藏不必要的細節(jié)。
- 繼承
類
class Person: def set_name(self, name): self.name = name def get_name(self): return self.name def greet(self): print("Hello, world! I'm {}.".format(self.name))
- self 指向?qū)ο蟊旧?#xff1a;
如果foo是一個Person實例,可將foo.greet()視為Person.greet(foo)的簡寫,但后者的多態(tài)性更低。
>>>class Cls:def func():print('no self')>>>Cls.func()
no self
>>>cls = Cls()
>>>cls.func()
Traceback (most recent call last):File "<pyshell#6>", line 1, in <module>cls.func()
TypeError: Cls.func() takes 0 positional arguments but 1 was given
- 私有:方法或?qū)傩猿蔀樗接械?#xff08;不能從外部訪問),只需讓其名稱以兩個下劃線打頭即可。
不希望名稱被修改,又想發(fā)出不要從外部修改屬性或方法的信號,可用一個下劃線打
頭。
- ‘遮蓋’
class MemberCounter: members = 0 def init(self): MemberCounter.members += 1# 新值被寫入m1的一個屬性中,這個屬性遮住了類級變量
>>> m1.members = 'Two'
>>> m1.members
'Two'
>>> m2.members
2
- 探討繼承關(guān)系
-
issubclass 確定一個類是否是另一個類的子類
-
isinstance 要確定對象是否是特定類的實例
-
bases 如果你有一個類,并想知道它的基類
-
class 如果你要獲悉對象屬于哪個類
- 接口和內(nèi)省
- hasattr(tc, ‘talk’) 檢查所需的方法是否存在
- getattr(tc, ‘talk’, None) 返回對象的屬性 callable(getattr(tc, ‘talk’, None)) callable 判斷對象是否是可調(diào)用的
- setattr 與getattr功能相反,可用于設(shè)置對象的屬性
- dict 要查看對象中存儲的所有值
內(nèi)省:模塊inspect
- 抽象基類和isinstance
>>>from abc import ABC, abstractmethod >>>class Talker(ABC): @abstractmethod def talk(self): pass>>> h = Herring()
>>> isinstance(h, Talker)
False# 可將Herring注冊為Talker
>>> Talker.register(Herring)
<class '__main__.Herring'>
>>> isinstance(h, Talker)
True
>>> issubclass(Herring, Talker)
True# 這種做法存在一個缺點,就是直接從抽象類派生提供的保障沒有了
>>> class Clam:
... pass
...
>>> Talker.register(Clam)
<class '__main__.Clam'>
>>> issubclass(Clam, Talker)
True
>>> c = Clam()
>>> isinstance(c, Talker)
True
>>> c.talk()
Traceback (most recent call last): File "<stdin>", line 1, in <module>
AttributeError: 'Clam' object has no attribute 'talk'
換而言之,應(yīng)將isinstance返回True視為一種意圖表達。在這里,Clam有成為Talker的意圖。本著鴨子類型的精神,我們相信它能承擔Talker的職責,但可悲的是它失敗了。
小結(jié)
對象:對象由屬性和方法組成。屬性不過是屬于對象的變量,而方法是存儲在屬性中的函數(shù)。相比于其他函數(shù),(關(guān)聯(lián)的)方法有一個不同之處,那就是它總是將其所屬的對象作為第一個參數(shù),而這個參數(shù)通常被命名為self。
類:類表示一組(或一類)對象,而每個對象都屬于特定的類。類的主要任務(wù)是定義其實例將包含的方法。
多態(tài):多態(tài)指的是能夠同樣地對待不同類型和類的對象,即無需知道對象屬于哪個類就可調(diào)用其方法。
封裝:對象可能隱藏(封裝)其內(nèi)部狀態(tài)。在有些語言中,這意味著對象的狀態(tài)(屬性)只能通過其方法來訪問。在Python中,所有的屬性都是公有的,但直接訪問對象的狀態(tài)時程序員應(yīng)謹慎行事,因為這可能在不經(jīng)意間導(dǎo)致狀態(tài)不一致。
繼承:一個類可以是一個或多個類的子類,在這種情況下,子類將繼承超類的所有方法。你可指定多個超類,通過這樣做可組合正交(獨立且不相關(guān))的功能。為此,一種常見的做法是使用一個核心超類以及一個或多個混合超類。
接口和內(nèi)省:一般而言,你無需過于深入地研究對象,而只依賴于多態(tài)來調(diào)用所需的方法。然而,如果要確定對象包含哪些方法或?qū)傩?#xff0c;有一些函數(shù)可供你用來完成這種工作。
抽象基類:使用模塊abc可創(chuàng)建抽象基類。抽象基類用于指定子類必須提供哪些功能,卻不實現(xiàn)這些功能。
面向?qū)ο笤O(shè)計:關(guān)于該如何進行面向?qū)ο笤O(shè)計以及是否該采用面向?qū)ο笤O(shè)計,有很多不同的觀點。無論你持什么樣的觀點,都必須深入理解問題,進而創(chuàng)建出易于理解的設(shè)計。