一、面向對象 1、面向過程 a、優點:極大的降低了寫程式的複雜度,只需要順著執行的步驟,堆疊代碼即可 b、缺點:一套流水線或者流程就是來解決一個問題,代碼就是牽一發而東莞全身 2、面向對象 a、優點:解決程式的擴展性,對某一個對象單獨修改,會立刻反應到整個體系中 b、缺點:可控性差,無法向面向過程的 ...
一、面向對象
1、面向過程
a、優點:極大的降低了寫程式的複雜度,只需要順著執行的步驟,堆疊代碼即可
b、缺點:一套流水線或者流程就是來解決一個問題,代碼就是牽一發而東莞全身
2、面向對象
a、優點:解決程式的擴展性,對某一個對象單獨修改,會立刻反應到整個體系中
b、缺點:可控性差,無法向面向過程的程式設計流水線式的可以很精準的預測問題的處理流程與結果,面向對象的程式一旦開始就有對象之間的交互解決問題。
3、 類:具有相同特征的一類事物(人、狗、老虎)
4、對象/實例:具體的某一個事物(隔壁阿花、樓下旺財)
5、實例化:類——>對象的過程
6、 在python中,用變數表示特征,用函數表示技能,因而具有相同特征和技能的一類事物就是‘類’,
7、對象是則是這一類事物中具體的一個
class Person: #定義一個人類 role = 'person' #人的角色屬性都是人 def walk(self): #人都可以走路,也就是有一個走路方法,也叫動態屬性 print("person is walking...")
class 類名: 類屬性 = None def __init__(self,對象屬性): self.對象屬性 = 對象屬性 def 方法名(self): pass 實例 = 類名(10) 實例.方法名()
8、類的兩種作用:屬性引用和實例化
9、屬性引用(類名.屬性)
class Person: #定義一個人類 role = 'person' #人的角色屬性都是人 def walk(self): #人都可以走路,也就是有一個走路方法 print("person is walking...") print(Person.role) #查看人的role屬性 print(Person.walk) #引用人的走路方法,註意,這裡不是在調用
10、例化:類名加括弧就是實例化,會自動觸發__init__函數的運行,可以用它來為每個實例定製自己的特征
class Person: #定義一個人類 role = 'person' #人的角色屬性都是人 def __init__(self,name): self.name = name # 每一個角色都有自己的昵稱; def walk(self): #人都可以走路,也就是有一個走路方法 print("person is walking...") print(Person.role) #查看人的role屬性 print(Person.walk) #引用人的走路方法,註意,這裡不是在調用
11、
類名 類名.類屬性 類名.方法名 實例 = 類名(參數,參數) #實例就是對象 實例 實例.方法名() 實例.對象屬性 實例增加屬性 實例.新的屬性名 = 1000 print(實例.新的屬性名)
12、關於self
self:在實例化時自動將對象/實例本身傳給__init__的第一個參數,你也可以給他起個別的名字.
對象/實例只有一種作用:屬性引用
class 類名: def __init__(self,參數1,參數2): self.對象的屬性1 = 參數1 self.對象的屬性2 = 參數2 def 方法名(self):pass def 方法名2(self):pass 對象名 = 類名(1,2) #對象就是實例,代表一個具體的東西 #類名() : 類名+括弧就是實例化一個類,相當於調用了__init__方法 #括弧里傳參數,參數不需要傳self,其他與init中的形參一一對應 #結果返回一個對象 對象名.對象的屬性1 #查看對象的屬性,直接用 對象名.屬性名 即可 對象名.方法名() #調用類中的方法,直接用 對象名.方法名() 即可
dir(類) #返回類中的所有名字列表 isinstance(對象,類) #判斷對象是否為類的實例 print(Person.__dict__) # 返回一個字典 key是屬性名,value是屬性值 print(Person.__module__) #person類所在的模塊 print(Person.__name__,type(Person.__name__)) #字元串數據類型的類名
13、類命名空間與對象、實例的命名空間
a、常見一個類就會創建一個類的名稱空間,用來儲存類中定義的所有名字,這些名字成為類的屬性
b、而類有兩種屬性:靜態屬性和動態屬性
- 靜態屬性就是直接在類中定義的變數
- 動態屬性就是定義在類中的方法
創建一個對象/實例就會創建一個對象/實例的名稱空間,存放對象/實例的名字,稱為對象/實例的屬性
面相對象的組合用法:
組合指的是,在一個類中以另外一個類的對象作為數據屬性,稱為類的組
列子:
from math import pi class Circular: def __init__(self,radius): self.radius=radius def area(self): return self.radius **2 * pi def perimeter(self): return 2 * self.radius * pi circu=Circular(10) print(circu.area()) print(circu.perimeter())圓的周長與面積
14、面向對象的三大特征
a、繼承
class Animal: #父類 基類 超類 def __init__(self,name,life_value,aggr): self.name = name self.life_value = life_value self.aggr = aggr class Person(Animal): #子類 派生類 pass class Dog(Animal): #子類 派生類 pass egg = Person('egon',1000,50) print(egg.name) print(egg.aggr
python2 class Dad: #經典類 class Dag(object) #新式類 python3 class Dad == class Dag(object) #新式類
1、繼承的語法
class 類名(父類名): 想在子類中實現調用父類的方法 在類內 ——super(子類名,self).方法名() 在類外面 ——super(子類名,對象名).方法名() 如果不指定繼承的父類,預設繼承object 子類可以使用父類的所有屬性和方法 如果子類有自己的方法就執行自己的的 如果是子類沒有的方法就執行父類的 如果子類父類都沒有這個方法就報錯
繼承、抽象、派生
繼承 是從大範圍到小範圍
抽象 小範圍到大範圍
派生 就是在父類的基礎上又產生子類——派生類
父類里沒有的 但子類有的 ——派生方法
派生屬性
方法的重寫
父類里有的方法,在子類里重新實現
2、繼承的兩種用途:
b:繼承基類的方法,並且做出自己的改變或者擴展(代碼重用)
a:聲明某個子類相容於某基類,定義一個介面類Interface,介面類中定義
了一些介面名(就是函數名)且並未實現介面的功能,子類繼承介面類,並且實現介面中的功能
b、封裝
1、優點:
a、將變化隔離
b、封裝使用
c、提高復用性
d、提高安全性
2、封裝原則:
a、將不需要對外提供的內容都隱藏起來
b、把屬性都隱藏起來提供公共方法對其訪問
3、私有變數和私有方法
a、在python中用雙劃線的開頭的的方式降屬性隱藏起來(設置私有的)
property屬性
property是一種特殊的屬性,訪問它時會執行一段功能(函數)然後返回值
c、多態:”多態指的是一類事物有多種形態(比如:老師.下課鈴響了(),學生.下課鈴響了(),老師執行的是下班操作,學生執行的是放學操作,雖然二者消息一樣,但是執行的效果不同)
多態指的是:一類實物有多種狀態
python自帶多態:
多態:同一類事物的多種狀態
python里處處都是多態,只是我們一般發現不了
操作的時候不需要關心這個對象的數據類型,你只要用就行了
15、反射
1、 反射:可以用字元串的方式去訪問對象的屬性,調用對象的方法(但是不能去訪問方法),python中一切皆對象,都可以使用反射。
2、反射有四種方法:
hasattr:hasattr(object,name)判斷一個對象是否有name屬性或者name方法。有就返回True,沒有就返回False
getattr:獲取對象的屬性或者方法,如果存在則列印出來。hasattr和getattr配套使用
需要註意的是,如果返回的是對象的方法,返回出來的是對象的記憶體地址,如果需要運行這個方法,可以在後面添加一對()
setattr:給對象的屬性賦值,若屬性不存在,先創建後賦值
delattr:刪除該對象指定的一個屬性
a、內置方法:isinstance和issubclass
isinstance(obj,cls)檢查是否obj是否是類 cls 的對象
class Foo: pass class Son(Foo): pass s=Son() print(isinstance(s,Son))
b、內置方法:issubclass(sub, super)檢查sub類是否是 super 類的派生類
class Foo(object): pass class Bar(Foo): pass issubclass(Bar, Foo)
c、python面向對象中的反射:通過字元串的形式操作對象相關的屬性,python中一切事物都是對象(都可以用反射)
檢查是否含有某屬性---hasattr 返回布爾值 獲取屬性---getattr 沒有就會報錯 設置屬性---setattr 刪除屬性---delattr
d、內置方法:__del__
析構方法,當對象在記憶體中被釋放時,自動觸發執行。
註:此方法一般無須定義,因為Python是一門高級語言,程式員在使用時無需關心記憶體的分配和釋放,因為此工作都是交給Python解釋器來執行,所以,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。
class Foo: def __del__(self): print('fgs') f=Foo() print(123) print(123) del f print(123) print(123) print(123)
e、內置方法:item系列
__getitem__\__setitem__\__delitem__
__new__
class A: def __init__(self): #有一個方法在幫你創造self print('in init function') self.x=1 def __new__(cls, *args, **kwargs): print('in init funct') return object.__new__(A,*args,**kwargs) a=A()
f、__str__和__repr__改變對象的字元串顯示
class Foo: 2 def __init__(self,name): 3 self.name = name 4 def __repr__(self): 5 return 'obj in str' #這裡只能是return 6 # def __str__(self): 7 # return '%s obj in str'%self.name 8 f = Foo('egon') 9 print(f) #優先執行__str__裡面的內容 10 # 那麼你是不是據地__repr__沒用呢? 11 # print('%s'%f) #執行的是__str__裡面的返回值 12 # print('%r'%f) #執行的是__repr__裡面的返回值 13 print('==============') 14 print(str(f)) #當執行str(f)時,會去找__str__這個方法,如果找不到的時候,__repr__這個方法就給替補了 15 print(repr(f)) 16 #1.當列印一個對象的時候,如果實現了__str__方法,列印__str__中的返回值 17 # 2.當__str__沒有被實現的時候,就會調用__repr__方法 18 # 3.但是當你用字元串格式化的時候,%s和%r會分別調用__str__和__repr__方法 19 # 4.不管是在字元串格式化的時候還是在列印對象的時候, 20 # __repr__方法都可以作為__str__方法的替補,但反之則不行 21 # 5.用於友好的表示對象。如果__str__和__repr__方法你只能實現一個:先實現__repr____str__,__repr__
15、內置方法
a、靜態方法和類方法
1、類方法:有個預設參數cls,並且可以直接用類名去調用,可以與類屬性交互(也就是可以使用類屬性)
2、靜態方法:讓類里的方法直接被類調用,就像正常調用函數一樣
b、類方法和靜態方法的相同點:都可以直接被類調用,不需要實例化
c、類方法和靜態方法的不同點:
類方法必須有一個cls參數表示這個類,可以使用類屬性
靜態方法不需要參數
d、綁定方法:分為普通方法和類方法
普通方法:預設有一個self對象傳進來,並且只能被對象調用-------綁定到對象
類方法:預設有一個cls對象傳進來,並且可以被類和對象(不推薦)調用-----綁定到類
e、非綁定方法:靜態方法:沒有設置預設參數,並且可以被類和對象(不推薦)調用-----非綁定
16、介面類與抽象類
a、 介面類:(在抽象類的基礎上)
在python中,預設是沒有介面類的
介面類不能被實例化(如果實例化會報錯)
介面類中的方法不能被實現
介面也就是做約束,讓下麵的類的方法都按照介面類中給出的方法去定義。如果介面類裡面有的方法類裡面沒有,那麼那個類就不能被實例化。(字面理解)
繼承的第二種含義非常重要。它又叫“介面繼承”。
介面繼承實質上是要求“做出一個良好的抽象,這個抽象規定了一個相容介面,使得外部調用者無需關心具體細節,可一視同仁的處理實現了特定介面的所有對象”——這在程式設計上,叫做歸一化。
b、抽象類
在python中,預設是有的
父類的方法,子類必須實現
抽象類(父類)的方法可以被實現
抽象類和介面類的區別:介面類不能實現方法,抽象類可以實現方法裡面的內容
抽象類和介面類的相同點:都是用來做約束的,都不能被實例化
抽象類和介面類的使用:
當幾個子類的父類有相同的功能需要被實現的時候就用抽象類
當幾個子類有相同的功能,但是實現各不相同的時候就用介面類