面向對象與面向過程
python是一門面向對象的編程語言,面向對象是一種編程思想,與之相對應的是面向過程。
1、面向過程
面向過程其實就是把過程當做設計核心,根據問題的發展順序,依次解決問題,盡可能的把過程中涉及到的問題完善解決。他有他的優點,當拿到一個問題時,可以方便的按執行的步驟寫代碼,但是當邏輯關系變得復雜時,有一個地方出現差錯就會導致整個程序無從下手。面向對象的編程語言還是很多的,例如C++、Java等等。
優點是:極大的降低了寫程序的復雜度,只需要順着要執行的步驟,堆疊代碼即可。
缺點是:一套流水線或者流程就是用來解決一個問題,代碼牽一發而動全身。
應用場景:一旦完成基本很少改變的場景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
2、面向對象
面向對象程序設計把計算機程序的執行看做一組對象的集合,每個對象之間進行消息的傳送處理。有一個顯著的優點就是,對某個對象進行修改,整個程序不會受到影響,自定義數據類型就是面向對象中的類的概念,而我們需要把他們的接口處理好就可以。
優點是:解決了程序的擴展性。對某一個對象單獨修改,會立刻反映到整個體系中,如對游戲中一個人物參數的特征和技能修改都很容易。
缺點:可控性差,無法向面向過程的程序設計流水線式的可以很精准的預測問題的處理流程與結果,面向對象的程序一旦開始就由對象之間的交互解決問題,即便是上帝也無法預測最終結果。
應用場景:需求經常變化的軟件,一般需求的變化都集中在用戶層,互聯網應用,企業內部軟件,游戲等都是面向對象的程序設計大顯身手的好地方。
類與對象
1、類:用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。即類是一個種類,一個模型。
2、對象(實例):類的實例。即根據模型制造出來的具體某個東西
3、實例化:從類到對象的過程。即從模型到成品東西的過程。
4、方法:類里面的函數
5、屬性:類里面的變量就為類的屬性。類有兩種屬性:靜態屬性和動態屬性
6、類的定義和使用實際操作:
self:代表的本類對象。在類中,代表本類對象;在類外,需要用具體的實例名代替self。My.say(m) 等同於m.say()
cls:在類中,代表本類;在類外,需要用具體的類名代替cls。
類變量:就在直接在類下面定義的變量,沒有加self的,每個實例都可以用
class Car: #定義類 wheel =4 #類變量,公共的,調用的時候沒有時,從公共變量中找。防止每個實例都定義的時候浪費內存 def __init__(self,color,brand): #self.wheel=wheel self.color = color #實例變量 self.brand = brand def help(self): #類中的方法 print('汽車有%s個輪子'%self.wheel) print('汽車的顏色是%s'%self.color) print('='*10) my = Car('赤橙黃綠青藍紫','我的') #類實例化 my.help()

類的函數
1、構造函數:類在實例化的時候會自動執行的一個函數
- 定義格式:
class 類名: def __init__(self,參數-若有):
- 調用:
#類外調用如下: 對象名=類名(參數-若有) # 1、創建實例對象並自動調用構造函數。 類名.__init__(對象名,參數-若有) # 2、已創建對象實例的前提下,執行構造函數。 對象名.__init__(參數-若有) # 3、實例.方法查找順序:實例方法→類方法
2、析構函數:實例在銷毀的時候自動執行的函數。一般關閉數據庫連接、關閉文件等操作可以寫在析構函數。
- 定義格式:
class 類名: def __del__(self):
- 調用:
# 類外調用如下 : # 1、無顯式銷毀實例時,則當程序運行結束后,自動銷毀實例,自動調用析構函數 del 對象名 # 2、顯式銷毀實例后,則立即自動調用析構函數 類名.__del__(對象名) # 3、直接調用析構函數。並沒有銷毀實例。
3、類方法:@classmethod標識
- 不需要實例化就可以調用
- 它可以使用類變量
- 調用其他的類方法。
- 它不可以使用實例方法、實例變量
- 如果類里面的這個方法,它並沒有使用到其他的實例變量、或者其他實例方法,那么就給他定義成類方法
定義格式:
class 類名: @classmethod def 方法名(cls,參數-若有):
調用:
#類內、類外調用如下: 類名.類方法(參數-若有) #類外調用如下: 對象名.類方法(參數-若有) # 實例.方法查找順序:實例方法→類方法 #類內調用如下: class 類名: @classmethod def 方法名(cls,參數-若有): cls.類方法(參數-若有) class 類名: def 方法名(self,參數-若有): self.類方法(參數-若有) # 方法名指所有能傳self的方法。 # self.方法查找順序:實例方法→類方法
class Car: wheel = 4 #類變量 def __init__(self,color,p): self.color = color #實例變量 self.p = p def help(self): print('汽車有%s個輪子'%self.wheel) print('汽車的顏色是%s'%self.color) print('牌子%s'%self.p) print('='*10) #self.haha() self.check_wheel() @classmethod #類方法 def check_wheel(cls): print('cls的內存地址',id(cls)) print(cls.wheel) Car.check_wheel()
4、靜態方法:@staticmethod 標識
- 不需要實例化就可以調用的
- 它就是一個定義在類里面的普通函數,不能使用實例變量、實例方法、不能使用類變量、類方法。
- 可以用靜態方法調用另一個靜態方法,如果改用類方法調用靜態方法,可以讓cls代替類,讓代碼看起來精簡一些。也防止類名修改了,不用在類定義中修改原來的類名。
- 定義格式:
class 類名: @staticmethod def 方法名(參數-若有):
- 調用:
#類外調用如下: 對象名.靜態方法 # 注意末尾沒有括號 #類內調用如下: class 類名: @classmethod def 方法名(cls,參數-若有): cls.靜態方法(參數-若有) class 類名: def 方法名(self,參數-若有): self.靜態方法(參數-若有) # 方法名指所有能傳self的方法。
class Car: wheel = 4 #類變量 def __init__(self,color,p): self.color = color #實例變量 self.p = p @staticmethod #靜態方法,誰都可以調用 def help2(): print('這個類的作用是造汽車,它里面有xxx方法') Car.help2()
5、屬性方法:@property 標識
適用於需要獲取方法返回值,而且沒有入參時使用。
看起來像變量的一個函數。
1、實例方法
2、調用不能有入參
3、用它的時候,直接m.func,把它當做一個變量用就ok了,不需要加括號調用
4、它是獲取函數的返回值
- 定義格式:
class 類名: @property def 方法名(self,參數-若有):
- 調用:
#類外調用如下: 對象名.屬性方法 # 注意末尾沒有括號 #類內調用如下: class 類名: def 方法名(self,參數-若有): print(self.屬性方法) # 方法名指所有能傳self的方法。
class Car: wheel = 4 #類變量 def __init__(self,color,p): self.color = color #實例變量 self.p = p @staticmethod #靜態方法,誰都可以調用 def help2(): print('這個類的作用是造汽車,它里面有xxx方法') @property #屬性方法 def yesterday(self): #昨天 import datetime res = datetime.date.today() + datetime.timedelta(-1) return str(res) Car.help2() my = Car('赤橙黃綠青藍紫','我的') print(my.yesterday)#注意沒有括號
6、實例方法:正常定義的類里的self函數都是實例方法,必須得實例化之后才可以使用。
- 定義格式:
class 類名: def 方法名(self,參數-若有):
- 調用:
#類外調用如下: 對象名.實例方法(參數-若有) #類內調用如下: class 類名: def 方法名(self,參數-若有): self.實例方法(參數-若有) # 方法名指所有能傳self的方法。
class Car: wheel = 4 #類變量 def __init__(self,color,p): self.color = color #實例變量 self.p = p def help(self): print('汽車有%s個輪子'%self.wheel) print('汽車的顏色是%s'%self.color) print('牌子%s'%self.p) print('='*10) self.haha() self.check_wheel() @classmethod def check_wheel(cls): print('cls的內存地址',id(cls)) print(cls.wheel) cls.haha() @classmethod def haha(cls): print('哈哈哈') cls.help2() @staticmethod def help2(): print('這個類的作用是造汽車,它里面有xxx方法')
7、私有方法:私有方法只能在類里面調用 ,不能在類外調用,子類也不可以調用。比如說連接數據庫client。私有變量也一樣,只能在類中使用
- 定義格式:
class 類名: #第一種 @classmethod def __方法名(cls,參數-若有):4 class 類名: #第二種 def __方法名(self,參數-若有):
- 調用:
#類內調用如下: class 類名: #第一種 @classmethod def 方法名(cls,參數-若有): cls.私有方法(參數-若有) class 類名: #第二種 def 方法名(self,參數-若有): self.私有方法(參數-若有) # 方法名指所有能傳self的方法。
class My: def test(self): self.__password=123456#私有變量,在類中可以用,出了類就不能使用 def say(self): self.__password=7890 def update(self): self.__set_password()
m= My()
m.test()
m.say()
m.update() #類外面不能使用,則報錯
變量
1、實例變量
什么時候用到實例變量?如一個變量值在本類的多個函數中都要用到的,可以聲明為實例變量。如連接數據庫使用頻繁,為了避免每次處理數據都要連接一次,可以將連接數據庫放在構造函數中。當然這個也可以放在實例方法中,具體看應用的頻繁程度。
- 定義格式:
class 類名: def 方法名(self,參數-若有): self.變量名 = 變量值 # 方法名指所有能傳self的方法。 類方法、靜態方法中不能定義實例變量。
- 調用:
如下: 對象名.實例變量 #第一種 #類內調用如下: self.實例變量 #第一種
2、私有變量
私有變量只能在類里面調用 ,不能在類外調用,子類也不可以調用。比如說連接數據庫client不想在類外被修改,所以使用私有變量__client就不會被修改到。私有變量會比較安全。
- 定義格式:
class 類名: #第一種 def 方法名(self,參數-若有): self.__變量名 = 變量值 # 方法名指所有能傳self的方法。 class 類名: #第二種 @classmethod def 方法名(cls,參數-若有): cls.__變量名 = 變量值 # 方法名指類方法。
- 調用:
#類內調用如下: self.__私有變量 #第一種 # 私有變量查找順序:非類私有變量->類私有變量 cls.__私有變量 #第二種:類私有變量
3、局部變量
- 定義格式:
class 類名: def 方法名(self/cls-若有,參數-若有): 變量名 = 變量值 # 方法名指所有方法。
- 調用
1 #本函數內調用如下: 2 局部變量名
4、全局變量
- 定義格式:
class 類名: def 方法名(self/cls-若有,參數-若有): global 變量名 變量名 = 變量值 # 方法名指所有方法。
- 調用:
1 #全局變量定義至程序結束作用域內調用如下: 2 全局變量名
面向對象特性--繼承
繼承是一種創建新類的方式,在python中,新建的類可以繼承一個或多個父類,父類又可稱為基類或超類,新建的類稱為派生類或子類
class ParentClass1: #定義父類 pass class ParentClass2: #定義父類 pass class SubClass1(ParentClass1): #單繼承,基類是ParentClass1,派生類是SubClass pass class SubClass2(ParentClass1,ParentClass2): #python支持多繼承,用逗號分隔開多個繼承的類 pass
class Lm: money=1000000 house = 5 def driver(self): print('開車') class Mcb(Lm):#繼承了父類,父類中有的他都有 def about_me(self): print('我有%s錢,%s房子'%(self.money,self.house)) self.driver() def driver(self): #子類有的時候,就不會繼承父類的方法 print('dddddd開車') print(Mcb.money) m=Mcb() m.about_me()
更多參考:
http://www.cnblogs.com/Eva-J/articles/7293890.html
https://www.cnblogs.com/benric/p/5064169.html
https://blog.csdn.net/qq_42156420/article/details/80567052
