日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python开发学习笔记之六(面向对象)

發布時間:2023/12/10 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python开发学习笔记之六(面向对象) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

面向對象引入:

  現在有一個這樣的需求:做汽水。

  在之前的學習中,我們怎樣處理這種類似的問題呢?思考一下,哦,不就是分步驟做嘛,把復雜的問題簡單化,分成一個一個的步驟,就像機器人,流水線一樣,先干什么后干什么,然后干什么,最后再干什么。于是這個問題就可以分解成這幾個步驟:

  制作汽水瓶———制作汽水————把汽水灌入汽水瓶————封口————貼標簽————打包裝箱

  這就是一套完整的汽水制作生產線,這就是典型的面向過程的程序設計思路。

  面向過程的優缺點:

    優點:復雜問題流程化,進而簡單化。將問題分解成步驟,逐個步驟進行處理

    缺點:針對性太強,一套方法只適用于一種需求,代碼的可重用性太低,只適用于一些一旦寫好不進行修改的場景。

  而面向對象是站在上帝角度來看待問題,上面做汽水的流水線,就可以看做是一個對象。這個對象可以做汽水瓶,可以做汽水,可以灌裝,等等一系列的操作。

  對象的概念就是:特征與技能的結合體(人就是個對象,人有名字年齡性別,這是特征;人會吃飯睡覺學習,這是技能。)

  面向對象的優缺點:

    優點:提高了代碼的擴展性,對某個對象進行修改,可以影響到整個代碼體系

    缺點:編程的復雜度提高,無法準確地預測最終結果。 適用于需求不斷變化的場景

?

類與對象:


?

  類即類別、種類,是面向對象設計最重要的概念,對象是特征與技能的結合體,而類則是一系列對象相似的特征與技能的結合體

  現實世界中,先有對象,后有類:

#在現實世界中,站在老男孩學校的角度:先有對象,再有類 對象1:李坦克特征:學校=oldboy姓名=李坦克性別=男年齡=18技能:學習吃飯睡覺對象2:王大炮特征:學校=oldboy姓名=王大炮性別=女年齡=38技能:學習吃飯睡覺對象3:牛榴彈特征:學校=oldboy姓名=牛榴彈性別=男年齡=78技能:學習吃飯睡覺現實中的oldboy學生類相似的特征:學校=oldboy相似的技能:學習吃飯睡覺 View Code

  在程序中,先定義類,后實例化出對象:

class Student:school = 'oldboy' # 相同的特征def __init__(self, name, age, sex) # 各自的特征self.name = nameself.age = ageself.sex = sexdef eat(self): # 相似的技能print('eating...')def learn(self):print('learning...')def sleep(self)print('sleeping...') View Code

?  上面的代碼就是定義了一個學生類

  獲得對象就是通過類實例化出來

stu1 = Student('zhangsan','18,'')

類的使用:

定義Student類:

class Student:school='oldboy'def learn(self):print('is learning')def eat(self):print('is eating')def sleep(self):print('is sleeping')

# 查看類的名稱空間
 Student.__dict__

查看類中的屬性:

  Student.__dict__['school']? ?就可以獲得類的數據屬性,python 專用的屬性訪問方法是 Student.school

設置類中的屬性:

  增加屬性:Student.county = 'China'  修改屬性:Student.school = 'OLDBOY'

刪除類中的屬性:

  del Student.school

?

對象的使用:

先生成三個對象:

  stu1 = Student()

  stu2 = Student()

  stu3 = Student()

這三個學生對象都有相同的學校和相同的技能,但是這三名學生也有各自獨有的屬性:姓名,年齡,性別,那么怎么個性化定制每個學生的信息呢?

這就用到了類內部的__init__方法,它在實例化出對象時就會執行,給對象創建出各自不同的屬性

# 定義類 class Student:school = 'oldboy'def __init__(self, name, age, sex): # 為對象定制各自的數據屬性self.Name = nameself.Age = ageself.Sex = sexdef eat(self):print('is eating...')def learn(self):print('is learning...')def sleep(self):print('is sleeping...')

# 實例化對象

stu1 = Student('zhangsan',18,'male')

它實例化的具體步驟是:先產生一個空對象,再通過__init__方法給空對象添加屬性

查看對象的屬性:

  stu1.name

  stu1.learn()

設置對象的屬性:

  增加屬性:stu1.class_name = 'python開發'  修改屬性:stu1.name = 'lisi'

刪除對象的屬性:

  del stu1.name

?

注意:在類中的數據屬性是所有對象所直接共有的,是同一個id;而類中的函數屬性是分別綁定到每個不同的對象,是不同的id.

當通過類調用類內部的方法時需要把對象當做參數傳入函數:

  Student.learn(stu1)

當實例化出一個對象時,對象會綁定類內的函數為對象自己的綁定方法。實際上,類內的函數屬性就是給對象使用的

而通過對象來調用自己的綁定方法時,會自動把對象傳入函數當做參數(誰來調用,就把誰當做參數傳入函數):

  stu1.learn()

查找屬性會先從對象自己內部查找屬性,如果對象內部沒有這個屬性,就會從這個對象的類里去查找屬性,類似與函數的局部變量與全局變量

?

補充:

  1.站的角度不同,定義的類也不同

  2.編程中可能定義現實生活中不存在的類,比如關系類,策略類等等

ps: python中一切皆對象,在python3中統一了類與類型的概念

練習一:

  編寫學生類,實例化一些學生對象,并加上計數器(屬性),統計實例化的對象個數:

class Student: # 生成學生類school = 'oldboy'count = 0 # 生成計數器def __init__(self, name, age, sex):self.Name = nameself.Age = ageself.Sex = sexStudent.count += 1 # 每實例化一個對象把類的計數器加一def eat(self):print('is eating...')def learn(self):print('is learning...')def sleep(self):print('is sleeping...')stu1 = Student('zhangsan', 18, 'male') stu2 = Student('lisi', 28, 'female') stu3 = Student('wangwu', 38, 'male')print(Student.count)

?

練習二:

  模仿LOL,生成游戲角色對象,角色可以互相攻擊

?

class Garen: # 定義蓋倫類def __init__(self, nickname, hp, ap):self.nickname = nicknameself.hp = hpself.ap = apdef attack(self, enemy):enemy.hp -= self.apclass Reven: # 定義瑞文類def __init__(self, nickname, hp, ap):self.nickname = nicknameself.hp = hpself.ap = apdef attack(self, enemy):enemy.hp -= self.apg = Garen('草叢倫', 500, 30)r = Reven('瑞雯雯', 300, 50)print('r', r.hp) g.attack(r) print('r', r.hp)

  看一下上面的代碼,你會發現兩個類內部的代碼是一模一樣的,那么如果再需要定義其他角色就要重復寫同樣的代碼,怎么解決代碼重復性的問題呢?

  這就需要了解一個概念:

繼承:

  繼承指的是類與類之間的關系,是一種什么“是”什么的關系,繼承的功能之一就是用來解決代碼重用問題

  繼承是一種創建新類的方式,在python中,新建的類可以繼承一個或多個父類,父類又可以成為基類或超類,新建的類稱為派生類或子類

class Hero:def __init__(self, nickname, hp, ap):self.nickname = nicknameself.hp = hpself.ap = apdef attack(self, enemy):enemy.hp -= self.apclass Garen(Hero):passclass Reven(Hero):passg = Garen('草叢倫', 500, 30)r = Reven('瑞雯雯', 300, 50)print('r', r.hp) g.attack(r) print('r', r.hp)

上面的代可以寫成這種形式,兩個角色類可以繼承英雄類,從而提高了代碼的復用性。

單繼承與多繼承

  在python中可以繼承多個父類:

class ParentClass1: #定義父類passclass ParentClass2: #定義父類passclass SubClass1(ParentClass1): #單繼承,基類是ParentClass1,派生類是SubClasspassclass SubClass2(ParentClass1,ParentClass2): #python支持多繼承,用逗號分隔開多個繼承的類pass

查看繼承關系:

SubClass1.__bases__

有了繼承關系,通過對象去查找屬性是就是這樣:

對象本身——對象的類————類的父類——...

一層一層的查找,找到就不往上找了

?

派生:

  子類也可以添加自己新的屬性或者在自己這里重新定義這些屬性(不會影響到父類),需要注意的是,一旦重新定義了自己的屬性且與父類重名,那么調用新增的屬性時,就以自己的屬性為準。

class Riven(Hero):camp='Noxus'def attack(self,enemy): #在自己這里定義新的attack,不再使用父類的attack,且不會影響父類print('from riven')def fly(self): #在自己這里定義新的print('%s is flying' %self.nickname)

繼承的實現原理

  當定義一個類時,python會為這個類生成一個方法解釋順序mro列表,為了實現繼承,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類為止。而這個MRO列表的構造是通過一個C3線性化算法來實現的。我們不去深究這個算法的數學原理,它實際上就是合并所有父類的MRO列表并遵循如下三條準則:

  • 子類會先于父類被檢查
  • 多個父類會根據它們在列表中的順序被檢查
  • 如果對下一個類存在兩個合法的選擇,選擇第一個父類
  •   在Java和C#中子類只能繼承一個父類,而Python中子類可以同時繼承多個父類,如果繼承了多個父類,那么屬性的查找方式有兩種,分別是:深度優先和廣度優先

    在python3中所有的類都是新式類,新式類就是在不指定繼承關系的情況下,默認繼承object類。在一系列的繼承之后,最頂端的父類必然是object類

    ?

    接下來思考一個問題,如果想在子類中想復用一下父類的方法,需要怎么辦呢?

    比如:

    class Hero:def __init__(self, nickname, hp, ap):self.nickname = nicknameself.hp = hpself.ap = apdef attack(self, enemy):enemy.hp -= self.ap
    class Garen(Hero):def attack(self, enemy):#<---在這里重用父類的攻擊方法print('Garen attack!')pass

    class Reven(Hero):passg = Garen('草叢倫', 500, 30) r = Reven('瑞雯雯', 300, 50)

    那么你可能會想到下面這種方法:

    class Hero:def __init__(self, nickname, hp, ap):self.nickname = nicknameself.hp = hpself.ap = apdef attack(self, enemy):enemy.hp -= self.apclass Garen(Hero):def attack(self, enemy):Hero.attack(self, enemy) #<---在這里重用父類的攻擊方法print('Garen attack!')passclass Reven(Hero):passg = Garen('草叢倫', 500, 30)r = Reven('瑞雯雯', 300, 50)

    這種就是指名道姓的調用方法,不依賴于繼承關系

    第二種就是依賴于繼承關系的?super()?方法:

    class Hero:def __init__(self, nickname, hp, ap):self.nickname = nicknameself.hp = hpself.ap = apdef attack(self, enemy):enemy.hp -= self.apclass Garen(Hero):def attack(self, enemy):super().attack(enemy) #<---在這里重用父類的攻擊方法print('Garen attack!')passclass Reven(Hero):passg = Garen('草叢倫', 500, 30)r = Reven('瑞雯雯', 300, 50)

    ?組合:

      組合指的就是是在一個類里以另一個類中的對象為數據屬性,也就是什么“有”什么的關系:

    舉個上文中的例子:

    >>> class Equip: #武器裝備類 ... def fire(self): ... print('release Fire skill') ... >>> class Riven: #英雄Riven的類,一個英雄需要有裝備,因而需要組合Equip類 ... camp='Noxus' ... def __init__(self,nickname): ... self.nickname=nickname ... self.equip=Equip() #用Equip類產生一個裝備,賦值給實例的equip屬性 ... >>> r1=Riven('銳雯雯') >>> r1.equip.fire() #可以使用組合的類產生的對象所持有的方法 release Fire skill

    組合與繼承都是有效地利用已有類的資源的重要方式。但是二者的概念和使用場景皆不同,

    1.繼承的方式

    通過繼承建立了派生類與基類之間的關系,它是一種'是'的所屬關系,比如白馬是馬,人是動物。

    當類之間有很多相同的功能,提取這些共同的功能做成基類,用繼承比較好,比如老師是人,學生是人

    2.組合的方式

    用組合的方式建立了類與組合的類之間的關系,它是一種‘有’的擁有關系,比如教授有生日,教授教python和linux課程,教授有學生s1、s2、s3...

    ?

    抽象類與歸一化:

    抽取子類比較相像的部分,統一規范類中的屬性調用方法,這用到了一個叫 abc 的模塊

    import abcclass Animal(metaclass=abc.ABCMeta):@abc.abstractmethoddef run(self):pass@abc.abstractmethoddef eat(self):passclass People(Animal):passclass Pig(Animal):def run(self):print('pig is runing')def eat(self):print('pig is eating')pig1 = Pig() peo1 = People()

    當People類沒有用抽象類規范的方法時就會報錯。通過抽象類實現了歸一化的作用。

    ?

    多態與多態性:

    ?

        

    ?

    ?

    ?

        

    ?

    轉載于:https://www.cnblogs.com/wilbur0402/p/9518340.html

    總結

    以上是生活随笔為你收集整理的python开发学习笔记之六(面向对象)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。