標籤:.class 執行個體化 http lis 連結 git 思路 匯入 函數的參數
一、物件導向概念1. "物件導向(OOP)"是什嗎?
簡單點說,“物件導向”是一種編程範式,而編程範式是按照不同的編程特點總結出來的編程方式。俗話說,條條大路通羅馬,也就說我們使用不同的方法都可以達到最終的目的,但是有些辦法比較快速、安全且效果好,有些方法則效率低下且效果不盡人意。同樣,編程也是為瞭解決問題,而解決問題可以有多種不同的視角和思路,前人把其中一些普遍適用且行之有效編程模式歸結為“範式”。常見的編程範式有:
面向過程編程:OPP(Procedure Oriented Programing)
物件導向編程:OOP(Object Oriented Programing)
函數式編程:(Functional Programing)
面向過程編程的步驟:
1)分析出解決問題所需要的步驟;
2)用函數把這些步驟一次實現;
3)一個一個地調用這些函數來解決問題;
面向過程的程式設計:核心是過程二字,過程指的是解決問題的步驟,即先幹什麼再幹什麼......面向過程的設計就好比精心設計好一條流水線,是一種機械式的思維方式。
優點是:複雜度的問題流程化,進而簡單化(一個複雜的問題,分成一個個小的步驟去實現,實現小的步驟將會非常簡單)
缺點是:一套流水線或者流程就是用來解決一個問題,生產汽水的流水線無法生產汽車,即便是能,也得是大改,改一個組件,牽一髮而動全身。
應用情境:一旦完成基本很少改變的情境,著名的例子有Linux內核,git,以及Apache HTTP Server等。
物件導向編程的步驟:
1)把構成問題的事務分解、抽象成各個對象;
2)結合這些對象的共有屬性,抽象出類;
3)類層次化結構設計--繼承 和 合成;
4)用類和執行個體進行設計和實現來解決問題。
物件導向的程式設計:核心是對象二字,,對象是特徵與技能的結合體,基於物件導向設計程式就好比在創造一個世界,你就是這個世界的上帝,存在的皆為對象,不存在的也可以創造出來,與面向過程機械式的思維方式形成鮮明對比,物件導向更加註重對現實世界的類比,是一種“上帝式”的思維方式。
優點是:易維護、易複用、易擴充,由於物件導向有封裝、繼承、多態性的特性,可以設計出低耦合的系統,使系統更加靈活、更加易於維護 .
缺點是:編程的複雜度遠高於面向過程,不瞭解物件導向而立即上手基於它設計程式,極容易出現過度設計的問題。 無法向面向過程的程式設計流水線式的可以很精準的預測問題的處理流程與結果。
應用情境:需求經常變化的軟體,一般需求的變化都集中在使用者層,互連網應用,企業內部軟體,遊戲等都是物件導向的程式設計大顯身手的好地方。
2. 物件導向編程的特點
物件導向編程達到了軟體工程的3個目標:重用性、靈活性、擴充性,而這些目標是通過以下幾個主要特點實現的:
3. 物件導向編程的使用情境
名詞解釋
類:一個類即是對一類擁有相同屬性的對象的抽象、藍圖、原型、模板。在類中定義了這些對象的都具備的屬性(variables(data))、共同的方法
屬性:人類包含很多特徵,把這些特徵用程式來描述的話,叫做屬性,比如年齡、身高、性別、姓名等都叫做屬性,一個類中,可以有多個屬性
方法:人類不止有身高、年齡、性別這些屬性,還能做好多事情,比如說話、走路、吃飯等,相比較於屬性是名詞,說話、走路是動詞,這些動詞用程式來描述就叫做方法。
執行個體(對象):一個對象即是一個類的執行個體化後執行個體,一個類必須經過執行個體化後方可在程式中調用,一個類可以執行個體化多個對象,每個對象亦可以有不同的屬性,就像人類是指所有人,每個人是指具體的對象,人與人之前有共性,亦有不同
執行個體化:把一個類生產一個對象的過程就叫執行個體化
在軟體系統運行時,類將被執行個體化成對象(Object),對象對應於某個具體的事物,是類的執行個體(Instance)
類即類別、種類,是物件導向設計最重要的概念,對象是特徵與技能的結合體,而類則是一系列對象相似的特徵與技能的結合體。
在現實世界中:先有對象,再有類
在現實世界中:先有對象,再有類:世界上肯定是先出現各種各樣的實際存在的物體,然後隨著人類文明的發展,人類站在不同的角度總結出了不同的種類,如人類、動物類、植物類等概念。
在程式中:務必保證先定義類,後產生對象
這與函數的使用是類似的,先定義函數,後調用函數,類也是一樣的,在程式中需要先定義類,後調用類
不一樣的是,調用函數會執行函數體代碼返回的是函數體執行的結果,而調用類會產生對象,返回的是對象。
例子:用嵌套函數來定義一個學校類
def school(name,addr,type): def init(name,addr,type): sch = { "name":name, "addr":addr, "type":type, "enrol_students":enrol_students, "exam":exam } return sch def enrol_students(school): print("%s正在招生"%school["name"]) def exam(school): print("%s正在考試"%school["name"]) return init(name,addr,type)s1 = school("清華","北京","公立")s1["enrol_students"](s1)
二、類屬性類有兩種屬性:資料屬性和函數屬性對象只有資料屬性,但是可以訪問類的函數屬性
1. 類的資料屬性是所有對象共用的
2. 類的函數屬性是綁定給對象用的
類中定義的函數(沒有被任何裝飾器裝飾的)是類的函數屬性,類可以使用,但必須遵循函數的參數規則,有幾個參數需要傳幾個參數。
類中定義的函數(沒有被任何裝飾器裝飾的),其實主要是給對象使用的,而且是綁定到對象的,雖然所有對象指向的都是相同的功能,但是綁定到不同的對象就是不同的Binder 方法。
強調:綁定到對象的方法的特殊之處在於,綁定給誰就由誰來調用,誰來調用,就會將‘誰’本身當做第一個參數傳給方法,即自動傳值(方法__init__也是一樣的道理)
增刪查改類的資料屬性
class Chinese: country = "China" ? def __init__(self,name): self.name = name ? p1 = Chinese("nick") # 查看類資料屬性 print(Chinese.country) ? # 增加類資料屬性 Chinese.minority = 56 print(Chinese.__dict__) print(p1.country) #China print(p1.minority) # 56 通過執行個體對象可以調用類的資料屬性 ? # 修改類資料屬性 Chinese.country = "CHINA" print(Chinese.__dict__) ? ? ? # 刪除類資料屬性 del Chinese.minority print(Chinese.__dict__)
增刪查改類的函數屬性
class Chinese: country = "China" ? def __init__(self,name): self.name = name ? def buy_house(self,house): print("%s正在買%s"%(self.name,house)) ? p1 = Chinese("nick") # 查看類函數屬性 Chinese.buy_house(p1,"別墅") ? ? # 增加類函數屬性 def shopping(self,place): print("%s正在%s買買買"%(self.name,place)) ? Chinese.shopping = shopping p1.shopping("巴黎") ? ? # 修改類函數屬性 def test(self,msg): print("test") Chinese.buy_house = test p1.buy_house("msg") ? ? # 刪除類函數屬性 print(Chinese.__dict__) del Chinese.buy_house print(Chinese.__dict__)
增刪查改對象的屬性
class Chinese: country = "China" ? def __init__(self,name,age): self.name = name self.age = age ? def buy_house(self,house): print("%s正在買%s"%(self.name,house)) ? p1 = Chinese("nick",18) # 查看對象屬性 print(p1.age) print(p1.buy_house) #對象與類的函數方法綁定了 ? # 增加對象的屬性 p1.gender = "male" #增加對象的資料屬性 print(p1.__dict__) ? def shopping(self,place): # 增加對象的函數屬性,對象原本只有資料屬性,這裡增加的函數屬性需要自己調用自己,無法用到類的__init__方法。 print("%s正在%s買買買"%(self.name,place)) p1.shopping = shopping p1.shopping(p1,"巴黎") print(p1.shopping) #只是普通函數,不是對象的Binder 方法,每個對象需要儲存函數屬性,無法實作類別的方法最佳化 print(p1.__dict__) ? # 修改對象屬性 p1.age = 20 #修改對象的資料屬性 print(p1.age) #20 ? # 不要修改對象的底層字典 p1.__dict__["age"] = 21 print(p1.age) ? ? # 刪除類函數屬性 del p1.age print(p1.__dict__)
注意
例子1
class Chinese: country = "China" li = ["a"] def __init__(self,name,age): self.name = name self.age = age ? def buy_house(self,house): print("%s正在買%s"%(self.name,house)) ? p1 = Chinese("nick",18) p1.li = [12,3] #這裡修改的是對象p1的l資料屬性,相當於新增加p1的li資料屬性 print(p1.__dict__) p1.li.append("b") #由於p1自己沒有li資料屬性,這裡增加的是類的資料屬性 print(p1.__dict__) print(Chinese.__dict__)
例子2
country = "中國" class Chinese: country = "China" ? def __init__(self,name,age): self.name = name self.age = age print("---",country) #這裡的country調用的結果是“中國”,而非"China",這裡的這個country,只是一個普通的變數 def buy_house(self,house): print("%s正在買%s"%(self.name,house)) ? p1 = Chinese("nick",18)
Python內建類屬性
__dict__ : 類的屬性(包含一個字典,由類的資料屬性群組成),一個字典,儲存類的所有的成員(包括屬性和方法)或執行個體對象中的所有成員屬性 ? __doc__ :類的文檔字串,類的描述資訊 ? __name__: 類名 ? __module__: 類定義所在的模組(類的全名是‘main.className‘,如果類位於一個匯入模組mymod中,那麼className.module 等於 mymod)。表示當前操作的對象對應的類的定義所在的模組名 ? __bases__ : 類的所有父類構成元素(包含了一個由所有父類組成的元組)
構造方法
__init__(...)被稱為 構造方法或初始化方法,在例執行個體化過程中自動執行,目的是初始化執行個體的一些屬性。每個執行個體通過__init__初始化的屬性都是專屬的
主要作用是執行個體化時給執行個體一些初始化參數,或執行一些其它的初始化工作,總之,因為這個__init__只要一執行個體化,就會自動執行。
普通方法
定義類的一些正常功能,就是類中沒有任何裝飾器的普通自訂函數。
或者這樣分類
類的成員可以分為三大類:欄位、方法和屬性
(一)欄位
欄位包括:普通欄位和靜態欄位,他們在定義和使用中有所區別,而最本質的區別是記憶體中儲存的位置不同,
class Province: ? # 靜態欄位 country = ‘中國‘ ? def __init__(self, name): ? # 普通欄位 self.name = name ? ? # 直接存取普通欄位 obj = Province(‘河北省‘) print obj.name ? # 直接存取靜態欄位 Province.country ?
欄位的定義和使用
分析:由上述代碼可以看出【普通欄位需要通過對象來訪問】【靜態欄位通過類訪問】,在使用上可以看出普通欄位和靜態欄位的歸屬是不同的。
靜態欄位在記憶體中只儲存一份
普通欄位在每個對象中都要儲存一份
(二)方法
方法包括:普通方法、靜態方法和類方法,三種方法在記憶體中都歸屬於類,區別在於調用方式不同。
class Foo: ? def __init__(self, name): self.name = name ? def ord_func(self): """ 定義普通方法,至少有一個self參數 """ ? # print self.name print ‘普通方法‘ ? @classmethod def class_func(cls): """ 定義類方法,至少有一個cls參數 """ ? print ‘類方法‘ ? @staticmethod def static_func(): """ 定義靜態方法 ,無預設參數""" ? print ‘靜態方法‘ ? ? # 調用普通方法 f = Foo() f.ord_func() ? # 調用類方法 Foo.class_func() ? # 調用靜態方法 Foo.static_func()
?
方法的定義和使用
(三)屬性
屬性的定義有兩種方式:
例子
class Goods(object): ? @property def price(self): print ‘@property‘ ? obj = Goods() obj.price # 自動執行 @property 修飾的 price 方法,並擷取方法的傳回值
參考連結
[1]http://www.cnblogs.com/yyds/p/7591804.html
[2]http://www.cnblogs.com/linhaifeng/articles/6182264.html
[3]https://www.cnblogs.com/wupeiqi/p/4766801.html
Python之路(第二十二篇) 物件導向初級:概念、類屬性