【Python基础】07、Python类与面向对象
一、面向對象編程(OOP)
程序=算法+數據結構=指令+數據
1、代碼可以選擇以指令為核心或以數據為核心進行編寫
兩種范型:
? ? ? ?以指令為核心:圍繞“正在發生什么”進行編寫
? ? ? ? ? ? ? 面向過程編程:程序具有一系列線性步驟;主體思想是代碼作用于數據
? ? ? ?以數據為核心:圍繞“將影響誰”進行編寫
? ? ? ? ? ? ? ?面向對象編程(OOP):圍繞數據及為數據嚴格定義的接口來組織程序, 用數據控制對代碼的訪問
2、面向對象的核心概念
所有編程語言的最終目的都是提供一種抽象方法
? ? ? ?在機器模型(“解空間”或“方案空間”)與實際解決的問題模型(“問題空間”)之間,程序員必須建立一種聯系
? ? ? ? ? ? ? ? 面向過程:程序 = 算法+數據結構
? ? ? ? ? ? ? ? 面向對象:將問題空間中的元素以及它們在解空間中的表示物抽象為對象,并允許通過問題來描述問題而不是方案
? ? ? ? ? ? ? ? ? ? ? ?可以把實例想象成一種新型變量,它保存著數據,但可以對自身的數據執行操作
類型由狀態集合(數據)和轉換這些狀態的操作集合組成
類抽象
? ? ? 類:定義了被多個同一類型對象共享的結構和行為(數據和代碼)
? ? ? 類的數據和代碼:即類的成員
? ? ? ? ? ? 數據:成員變量或實例變量
? ? ? ? ? ? 成員方法:簡稱為方法,是操作數據的代碼,用于定義如何使用成員變量;因此一個類的行為和接口是通過方法來定義的
? ? ?方法和變量:
? ? ? ? ? ? 私有:內部使用
? ? ? ? ? ? 公共:外部可見
3、面向對象的程序設計方法?
所有東西都是對象
程序是一大堆對象的組合
? ? ? ?通過消息傳遞,各對象知道自己該做什么
? ? ? ?消息:即調用請求,它調用的是從屬于目標對象的一個方法
每個對象都有自己的存儲空間,并可容納其它對象
? ? ? ? 通過封裝現有對象,可以制作成新型對象
每個對象都屬于某一類型
? ? ? ? 類型,也即類
? ? ? ? 對象是類的實例
? ? ? ? 類的一個重要特性為“能發什么樣的消息給它” ? ?#調用實例的方法就相當于對實例發消息
同一個類的所有對象都能接收相同的消息
4、對象的接口
定義一個類后,可以根據需要實例化出多個對象
如何利用對象完成真正有用的工作?
? ? ? ? 必須有一種辦法能向對象發出請求,令其做一些事情
? ? ? ? 每個對象僅能接受特定的請求
? ? ? ? ? ? ? ?能向對象發送的請求由其“接口”進行定義
? ? ? ? ? ? ? ? 對象的“類型”或“類”則規定了它的接口形式
5、對上面的概念的總結
類:將同一種具體物事的共同特性抽象出來的表現
? ? ? ?狀態和轉換這些狀態的操作(就是屬性和方法)
? ? ? ?數據:
? ? ? ? ? ? ? ? 變量:就是屬性
? ? ? ?方法:
? ? ? ? ? ? ? ? 函數:操作變量的代碼
6、類間關系
依賴('uses-a')
? ? ? ? 一個類的方法操縱另一個類的對象
聚合(‘has-a’)
? ? ? ? 類A的對象包含類B的對象
繼承(“is-a”)
? ? ? ? 描述特殊與一般關系
二、面向對象編程的原則
面向對象的模型機制有3個原則:封裝,繼承及多態
1、封裝(Encapsulation)
? ? ? ?隱藏實現方案細節
? ? ? ?將代碼及其處理的數據綁定在一起的一種編程機制,用于保證程序和數據不受外部干擾且不會被誤用
2、繼承(Inheritance)
一個對象獲得另一個對象屬性的過程;用于實現按層分類的概念
一個深度繼承的子類繼承了類層次中它的每個祖先的所有屬性
超類、基類、父類
子類、派生類
3、多態性(Polymorphism)
允許一個接口被多個通用的類動作使用的特性,具體使用哪個動作與應用場合相關
“一個接口,多個方法”
? ? ? ? ?用于為一組相關的動作設計一個通用的接口,以降低程序復雜性
三、Python類和實例
1、python類和實例
類是一種數據結構,可用于創建實例
? ? ? ? 一般情況下,類封裝了數據和可用于該數據的方法
Python類是一個可調用對象,即類對象
Python2.2之后,類是一種自定義類型,而實例則是聲明某個自定義類型的變量
2、Python中創建類
Python使用class關鍵字創建類,語法格式如下:
? ? ? class ClassName(bases):
? ? ? ? ? ? ‘class documentation string’
? ? ? ? ? ? ? ? class_suite
超類是一個或多個用于繼承的父類的集合
類體可以包含:聲明語句、類成員定義、數據屬性、方法
注意:
? ? ? 如果不存在繼承關系,ClassName后面的“(bases)”可以不提供
? ? ? 類文檔為可選
class語句的一般形式
class ClassName(bases):
? ? ? ? ?data = value ? ? ? ? ? ? ? ? ? ? ? #定義數據屬性
? ? ? ? ?def method(self,…): ? ? ? ? ? #定義方法屬性
? ? ? ? ? ? ? ? ?self.member = value
3、實例初始化
通過調用類來創建實例
? ? ?instance(自定義的實例名) = ClassName(args…)
類在實例化時可以使用__init__和__del__兩個特殊的方法
例子:
Python中,class語句類似def,是可執行代碼;直到運行class語句后類才會存在
class語句內,任何賦值語句都會創建類屬性
每個實例對象都會繼承類的屬性并獲得自己的名稱空間
In?[1]:?s1="xj"In?[2]:?type(s1) Out[2]:?strIn?[21]:?type(str) Out[21]:?typeIn?[22]:?type(list) Out[22]:?typeIn?[3]:?str. str.capitalize??str.format??????str.isupper?????str.rfind???????str.startswith str.center??????str.index???????str.join????????str.rindex??????str.strip str.count???????str.isalnum?????str.ljust???????str.rjust???????str.swapcase str.decode??????str.isalpha?????str.lower???????str.rpartition??str.title str.encode??????str.isdigit?????str.lstrip??????str.rsplit??????str.translate str.endswith????str.islower?????str.mro?????????str.rstrip??????str.upper str.expandtabs??str.isspace?????str.partition???str.split???????str.zfill str.find????????str.istitle?????str.replace?????str.splitlines??In?[3]:?s1. s1.capitalize??s1.find????????s1.isspace?????s1.partition???s1.rstrip??????s1.translate s1.center??????s1.format??????s1.istitle?????s1.replace?????s1.split???????s1.upper s1.count???????s1.index???????s1.isupper?????s1.rfind???????s1.splitlines??s1.zfill s1.decode??????s1.isalnum?????s1.join????????s1.rindex??????s1.startswith?? s1.encode??????s1.isalpha?????s1.ljust???????s1.rjust???????s1.strip??????? s1.endswith????s1.isdigit?????s1.lower???????s1.rpartition??s1.swapcase???? s1.expandtabs??s1.islower?????s1.lstrip??????s1.rsplit??????s1.title??In?[3]:?class?FirstClass:...:?????spam=30...:?????def?display(self):...:?????????print?self.spam...:?????????In?[4]:?x=FirstClassIn?[5]:?type(FirstClass) Out[5]:?classobj????????????????????#自定義類類型In?[6]:?type(x) Out[6]:?classobj?????????????In?[9]:?x. x.display??x.spam?????In?[9]:?x.spam Out[9]:?30In?[10]:?x.display Out[10]:?<unbound?method?FirstClass.display>In?[11]:?x.display() --------------------------------------------------------------------------- TypeError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-11-ef2c4eba88c5>?in?<module>() ---->?1?x.display()TypeError:?unbound?method?display()?must?be?called?with?FirstClass?instance?as?first?argument?(got?nothing?instead)In?[12]:?x.display(self) --------------------------------------------------------------------------- NameError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-12-0a0d07c21014>?in?<module>() ---->?1?x.display(self)NameError:?name?'self'?is?not?definedIn?[13]:?x=FirstClass()In?[14]:?type(FirstClass) Out[14]:?classobjIn?[15]:?type(x) Out[15]:?instance??????????????????#自定義類型的實例(變量)In?[25]:?type(FirstClass()) Out[25]:?instanceIn?[16]:?x. x.display??x.spam?????In?[17]:?x.spam Out[17]:?30In?[18]:?x.display Out[18]:?<bound?method?FirstClass.display?of?<__main__.FirstClass?instance?at?0x1e76998>>In?[19]:?x.display() 304、Python類方法及調用
實例(對象)通常包含屬性
? ? ? ?可調用的屬性:方法
? ? ? ? ? ? ? object.method()
? ? ? ?數據屬性
在OOP中,實例就像是帶有“數據”的記錄,而類是處理這些記錄的“程序”
? ? ? 通過實例調用方法相當于調用所屬類的方法來處理當前實例
? ? ? ? ? ? ?類似instance.method(args…)會被自動轉換為class.method(instance,args…)
? ? ? ? ? ? ? ? ? ? ?如前面的例子,x.display()會被自動轉換為FirstClass.display(x),即調用類的方法來處理實例x
因此,類中每個方法必須具有self參數,它隱含當前實例之意
在方法內對self屬性做賦值運算會產生每個實例自己的屬性
Python規定,沒有實例,方法不允許被調用,此即為“綁定”
In?[38]:?l1=[1,2,3]In?[39]:?l1. l1.append???l1.extend???l1.insert???l1.remove???l1.sort????? l1.count????l1.index????l1.pop??????l1.reverse??In?[39]:?list. list.append???list.extend???list.insert???list.pop??????list.reverse?? list.count????list.index????list.mro??????list.remove???list.sort?????In?[39]:?list.pop Out[39]:?<method?'pop'?of?'list'?objects>In?[40]:?list.pop() --------------------------------------------------------------------------- TypeError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-40-38a37a7ebeb6>?in?<module>() ---->?1?list.pop()TypeError:?descriptor?'pop'?of?'list'?object?needs?an?argumentIn?[41]:?list.pop(l1) Out[41]:?3In?[42]:?l1 Out[42]:?[1,?2]In?[55]:?class?FirstClass():spam=30def?display(self):print?self.spam....:?????????In?[56]:?x=FirstClass()In?[57]:?type(x) Out[57]:?instanceIn?[58]:?x.spam Out[58]:?30In?[59]:?x.display Out[59]:?<bound?method?FirstClass.display?of?<__main__.FirstClass?instance?at?0x1eedb00>>In?[60]:?x.display() 30In?[61]:?FirstClass. FirstClass.display??FirstClass.spam?????In?[61]:?FirstClass.spam Out[61]:?30In?[62]:?FirstClass.display Out[62]:?<unbound?method?FirstClass.display>In?[63]:?FirstClass.display() --------------------------------------------------------------------------- TypeError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-63-f86eed380e7e>?in?<module>() ---->?1?FirstClass.display()TypeError:?unbound?method?display()?must?be?called?with?FirstClass?instance?as?first?argument?(got?nothing?instead)In?[64]:?FirstClass.display(x) 305、Python類和實例的屬性
In?[3]:?class?MyClass():gender='Male'def?setName(self,who):self.name=who...:?????????In?[4]:?x=MyClass()In?[5]:?x. x.gender???x.setName??In?[5]:?x.gender Out[5]:?'Male'In?[19]:?x.gender() --------------------------------------------------------------------------- TypeError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-19-30286d5d5900>?in?<module>() ---->?1?x.gender()TypeError:?'str'?object?is?not?callableIn?[20]:?x.setName Out[20]:?<bound?method?MyClass.setName?of?<__main__.MyClass?instance?at?0x253ec20>>In?[21]:?x.setName() --------------------------------------------------------------------------- TypeError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-21-6315c358874f>?in?<module>() ---->?1?x.setName()TypeError:?setName()?takes?exactly?2?arguments?(1?given)In?[23]:?x.setName('xj')In?[24]:?x. x.gender???x.name?????x.setName??In?[24]:?x.setName Out[24]:?<bound?method?MyClass.setName?of?<__main__.MyClass?instance?at?0x253ec20>>In?[25]:?x.name Out[25]:?'xj'In?[26]:?x.name() --------------------------------------------------------------------------- TypeError?????????????????????????????????Traceback?(most?recent?call?last) <ipython-input-26-efd80cafd8e3>?in?<module>() ---->?1?x.name()TypeError:?'str'?object?is?not?callablePython構造器
創建實例時,Python會自動調用類中的__init__方法,以隱性地為實例提供屬性
? ? ? ?__init__方法被稱為構造器
? ? ? ?如果類中沒有定義__init__方法,實例創建之初僅是一個簡單的名稱空間
例子:
6、類的特殊屬性
? ? ? 可以使用類的__dict__字典屬性或Python內置的dir()函數來獲取類的屬性
實例屬性
實例僅擁有數據屬性(嚴格意義上來說,方法是類屬性)
? ? ? ? 通常通過構造器“__init__”為實例提供屬性
? ? ? ? 這些數據屬性獨立于其它實例或類
? ? ? ? 實例釋放時,其屬性也將被清除
內建函數dir()或實例的特殊屬性__dict__可用于查看實例屬性
7、Python類方法中可用的變量
方法的可用變量
? ? ? ?實例變量:指定變量名稱及實例自身進行引用
? ? ? ? ? ? ? self.變量名
? ? ? ?局部變量:方法內部創建的變量,可直接使用
? ? ? ?類變量(也稱靜態變量):通過指定變量名與類名進行引用
? ? ? ? ? ? ? 類名.變量名
? ? ? ?全局變量:直接使用
四、繼承
1、繼承
繼承描述了基類的屬性如何“遺傳”給派生類
? ? ? ?子類可以繼承它的基類的任何屬性,包括數據屬性和方法
? ? ? ? 一個未指定基類的類,其默認有一個名為object的基類
? ? ? ? Python允許多重繼承
2、創建子類
創建子類時,只需要在類名后跟一個或從其中派生的父類
class SubClassName(ParentClass1[, ParentClass2, …])
? ? ‘optional class documentation string’
? ? ? ?class_suite
3、Python類的繼承和屬性搜索
Python中幾乎所有屬性的獲取都可以使用“object.attribute” 的格式
? ? ? ? 不過,此表達式會在Python中啟動搜索——搜索連續的樹
class語句會產生一個類對象,對class的調用會創建實例,實例自動連結至創建了此實例的類
類連結至其超類的方式:
? ? ? ?將超類列在類頭部的括號內,其從左至右的順序會決定樹中的次序
? ? ? ?由下至上,由左至右
C1 ? ??C2
? ? ?C3
? ? ? I1
圖中所有的對象都是名稱空間,而繼承就是由下而上搜索此
4、繼承方法專用化
繼承會先在子類尋找變量名,然后才查找超類,因此,子類可以對超類的屬性重新定義來取代繼承而來的行為
? ? ? ?子類可以完全取代從超類繼承而來的屬性
? ? ? ?也可以通過已覆蓋的方法回調超類來擴展超類的方法
五、類、實例和其它對象的內建函數
issubclass()
? ? ? ?布爾函數,判斷一個類是否由另一個類派生,
語法:
? ? ? ? ? ? issubclass(sub, sup)
isinstance()
? ? ? ? 布爾函數,判斷一個對象是否是給定類的實例,
語法:
? ? ? ? ? ? isinstance(obj1, class_obj2)
hasattr()
? ? ? ? ?布爾函數,判斷一個對象是否擁有指定的屬性,
語法:
? ? ? ? ? ? hasattr(obj, ‘attr’)
同類的函數還有getattr()、setattr()和delattr()
super()
? ? ? ? 在子類中找出其父類以便于調用其屬性
? ? ? ? 一般情況下僅能采用非綁定方式調用祖先類方法
? ? ? ? 而super()可用于傳入實例或類型對象,
語法:
? ? ? ? super(當前類名[, obj])
調用父類的同名方法
? 擴展父類的同名方法
? super方法和super對象?
super(LockableDoor, self).__init__().__init(num,status) ? ? ?
? ? ? ?#代表父類 ? ?調用父類屬性
2、運算符重載
運算符重載是指在方法中攔截內置的操作——當類的實例出現在內置操作中,Python會自動調用自定義的方法,并且返回自定義方法的操作結果
? ? ? 運算符重載讓類攔截常規的Python運算
? ? ? ? ? ? ? 類可重載所有Python表達式運算符
? ? ? ? ? ? ? 類也可重載打印、函數調用、屬性點號運算等內置運算
? ? ? 重載使類實例的行為像內置類型
? ? ? 重載通過提供特殊名稱的類方法實現
運算符重載并非必需,并且通常也不是默認的
3、基于特殊的方法定制類
除了__init__和__del__之外,Python類支持使用許多的特殊方法
? ? ? 特殊方法都以雙下劃線開頭和結尾,有些特殊方法有默認行為, 沒有默認行為的是為了留到需要的時候再實現
? ? ? ?這些特殊方法是Python中用來擴充類的強大工具,它們可以實現
? ? ? ? ? ? ? 模擬標準類型
? ? ? ? ? ? ? 重載操作符
? ? ? ? 特殊方法允許類通過重載標準操作符+,*,甚至包括分段下標及映射操作[]來模擬標準類型
轉載于:https://blog.51cto.com/xiexiaojun/1861205
總結
以上是生活随笔為你收集整理的【Python基础】07、Python类与面向对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在 Msys pacman安装vim后遇
- 下一篇: websocket python爬虫_p