一、面向對象
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) #引用人的走路方法,注意,這里不是在調用。小編推薦一個學Python的學習裙【五八八,零九零,九四二】,無論你是大牛還是小白,是想轉行還是想入行都可以來了解一起進步一起學習!裙內有很多干貨和技術分享
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、
類名
類名.類屬性
類名.方法名
實例 = 類名(參數,參數) #實例就是對象實例
實例.方法名()
實例.對象屬性
實例增加屬性
實例.新的屬性名 = 1000print(實例.新的屬性名)
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、而類有兩種屬性:靜態屬性和動態屬性
靜態屬性就是直接在類中定義的變量
動態屬性就是定義在類中的方法
創建一個對象/實例就會創建一個對象/實例的名稱空間,存放對象/實例的名字,稱為對象/實例的屬性
面相對象的組合用法:
組合指的是,在一個類中以另外一個類的對象作為數據屬性,稱為類的組
列子:
圓的周長與面積
14、面向對象的三大特征
a、繼承
class Animal: #父類 基類 超類
def __init__(self,name,life_value,aggr):
self.name = name
self.life_value = life_value
self.aggr = aggrclass Person(Animal): #子類 派生類
passclass Dog(Animal): #子類 派生類
passegg = Person('egon',1000,50)print(egg.name)print(egg.aggr
python2class Dad: #經典類class Dag(object) #新式類python3class 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: passclass Son(Foo): passs=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 fprint(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__改變對象的字符串顯示
__str__,__repr__
15、內置方法
a、靜態方法和類方法
1、類方法:有個默認參數cls,并且可以直接用類名去調用,可以與類屬性交互(也就是可以使用類屬性)
2、靜態方法:讓類里的方法直接被類調用,就像正常調用函數一樣
b、類方法和靜態方法的相同點:都可以直接被類調用,不需要實例化
c、類方法和靜態方法的不同點:
類方法必須有一個cls參數表示這個類,可以使用類屬性
靜態方法不需要參數
d、綁定方法:分為普通方法和類方法
普通方法:默認有一個self對象傳進來,并且只能被對象調用-------綁定到對象
類方法:默認有一個cls對象傳進來,并且可以被類和對象(不推薦)調用-----綁定到類
e、非綁定方法:靜態方法:沒有設置默認參數,并且可以被類和對象(不推薦)調用-----非綁定
16、接口類與抽象類
a、 接口類:(在抽象類的基礎上)
在python中,默認是沒有接口類的
接口類不能被實例化(如果實例化會報錯)
接口類中的方法不能被實現
接口也就是做約束,讓下面的類的方法都按照接口類中給出的方法去定義。如果接口類里面有的方法類里面沒有,那么那個類就不能被實例化。(字面理解)
繼承的第二種含義非常重要。它又叫“接口繼承”。
接口繼承實質上是要求“做出一個良好的抽象,這個抽象規定了一個兼容接口,使得外部調用者無需關心具體細節,可一視同仁的處理實現了特定接口的所有對象”——這在程序設計上,叫做歸一化。
b、抽象類
在python中,默認是有的
父類的方法,子類必須實現
抽象類(父類)的方法可以被實現
抽象類和接口類的區別:接口類不能實現方法,抽象類可以實現方法里面的內容
抽象類和接口類的相同點:都是用來做約束的,都不能被實例化
抽象類和接口類的使用:
當幾個子類的父類有相同的功能需要被實現的時候就用抽象類
當幾個子類有相同的功能,但是實現各不相同的時候就用接口類