python基礎(23):面向過程與面向對象的優劣、初識面向對象

1. 面向過程與面向對象的優劣

面向過程的程序設計的核心是過程(流水線式思惟),過程即解決問題的步驟,面向過程的設計就比如精心設計好一條流水線,考慮周全何時處理什麼東西。python

優勢是:極大的下降了寫程序的複雜度,只須要順着要執行的步驟,堆疊代碼便可。git

缺點是:一套流水線或者流程就是用來解決一個問題,代碼牽一髮而動全身。編程

應用場景:一旦完成基本不多改變的場景,著名的例子有Linux內核,git,以及Apache HTTP Server等。數據結構

面向對象的程序設計的核心是對象(上帝式思惟),要理解對象爲什麼物,必須把本身當成上帝,上帝眼裏世間存在的萬物皆爲對象,不存在的也能夠創造出來。面向對象的程序設計比如如來設計西遊記,如來要解決的問題是把經書傳給東土大唐,如來想了想解決這個問題須要四我的:唐僧,沙和尚,豬八戒,孫悟空,每一個人都有各自的特徵和技能(這就是對象的概念,特徵和技能分別對應對象的屬性和方法),然而這並很差玩,因而如來又安排了一羣妖魔鬼怪,爲了防止師徒四人在取經路上被搞死,又安排了一羣神仙保駕護航,這些都是對象。而後取經開始,師徒四人與妖魔鬼怪神仙互相纏鬥着直到最後取得真經。如來根本不會管師徒四人按照什麼流程去取。函數

面向對象的程序設計的spa

優勢是:解決了程序的擴展性。對某一個對象單獨修改,會馬上反映到整個體系中,如對遊戲中一我的物參數的特徵和技能修改都很容易。設計

缺點:可控性差,沒法向面向過程的程序設計流水線式的能夠很精準的預測問題的處理流程與結果,面向對象的程序一旦開始就由對象之間的交互解決問題即使是上帝也沒法預測最終結果。因而咱們常常看到一個遊戲人某一參數的修改極有可能致使陰霸的技能出現,一刀砍死3我的,這個遊戲就失去平衡。code

應用場景:需求常常變化的軟件,通常需求的變化都集中在用戶層,互聯網應用,企業內部軟件,遊戲等都是面向對象的程序設計大顯身手的好地方。對象

在python 中面向對象的程序設計並非所有。blog

面向對象編程可使程序的維護和擴展變得更簡單,而且能夠大大提升程序開發效率 ,另外,基於面向對象的程序可使它人更加容易理解你的代碼邏輯,從而使團隊開發變得更從容。

瞭解一些名詞:類、對象、實例、實例化

類:具備相同特徵的一類事物(人、狗、老虎)

對象/實例:具體的某一個事物(隔壁阿花、樓下旺財)

實例化:類——>對象的過程(這在生活中表現的不明顯,咱們在後面再慢慢解釋)

2. 初識面向對象

python中一切皆爲對象,類型的本質就是類,因此,無論你信不信,你已經使用了很長時間的類了。

>>> dict #類型dict就是類dict
<class 'dict'>
>>> d=dict(name='eva') #實例化
>>> d.pop('name') #向d發一條消息,執行d的方法pop
'eva'

從上面的例子來看,字典就是一類數據結構,我一說字典你就知道是那個用{}表示,裏面由k-v鍵值對的東西,它還具備一些增刪改查的方法。可是我一說字典你能知道字典裏具體存了哪些內容麼?不能,因此咱們說對於一個類來講,它具備相同的特徵屬性和方法。

而具體的{'name':'eva'}這個字典,它是一個字典,可使用字典的全部方法,而且裏面有了具體的值,它就是字典的一個對象。對象就是已經實實在在存在的某一個具體的個體。

再舉一個其餘的例子,通俗一點,好比你如今有一個動物園,你想描述這個動物園,那麼動物園裏的每一種動物就是一個類,老虎、天鵝、鱷魚、熊。他們都有相同的屬性,好比身高體重出生時間和品種,還有各類動做,好比鱷魚會游泳,天鵝會飛,老虎會跑,熊會吃。

可是這些老虎熊啥的都不是具體的某一隻,而是一類動物。雖然他們都有身高體重,可是你卻沒有辦法肯定這個值是多少。若是這個時候給你一隻具體的老虎,而你還沒死,那你就能給他量量身高稱稱體重,這些數值是否是就變成具體的了?那麼具體的這一隻老虎就是一個具體的實例,也是一個對象。不止這一隻,其實每一隻具體的老虎都有本身的身高體重,那麼每一隻老虎都是老虎類的一個對象。

在python中,用變量表示特徵,用函數表示技能,於是具備相同特徵和技能的一類事物就是‘類’,對象是則是這一類事物中具體的一個。

3. 類

3.1 初識類

格式:

class 類名:
    類體

咱們建立一個類:

class Person:   #定義一我的類
  role = 'person'  #人的角色屬性都是人
  def walk(self):  #人均可以走路,也就是有一個走路方法,也叫動態屬性
    print("person is walking...")

3.2 類的做用

3.2.1 屬性引用(類名.屬性)

class Person:   #定義一我的類
  role = 'person'  #人的角色屬性都是人
  def walk(self):  #人均可以走路,也就是有一個走路方法
    print("person is walking...")

print(Person.role)  #查看人的role屬性
print(Person.walk)  #引用人的走路方法,注意,這裏不是在調用

3.2.2 實例化

類名加括號就是實例化,會自動觸發__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)  #引用人的走路方法,注意,這裏不是在調用

實例化的過程就是類——>對象的過程

本來咱們只有一個Person類,在這個過程當中,產生了一個對象,有本身具體的名字、攻擊力和生命值。

語法:

對象名 = 類名(參數)

p = Person('egon')  #類名()就等於在執行Person.__init__()
#執行完__init__()就會返回一個對象。這個對象相似一個字典,存着屬於這我的自己的一些屬性和方法。

3.2.3 查看屬性和調用方法

print(egg.name)     #查看屬性直接 對象名.屬性名
print(egg.walk())   #調用方法,對象名.方法名()

3.2.4 self

self:在實例化時自動將對象/實例自己傳給__init__的第一個參數,你也能夠給他起個別的名字,可是正常人都不會這麼作。由於修改後其餘人就不認識了。

3.2.5 類屬性的補充

一:咱們定義的類的屬性到底存到哪裏了?有兩種方式查看

dir(類名):查出的是一個名字列表
類名.__dict__:查出的是一個字典,key爲屬性名,value爲屬性值

二:特殊的類屬性

類名.__name__# 類的名字(字符串)
類名.__doc__# 類的文檔字符串
類名.__base__# 類的第一個父類(在講繼承時會講)
類名.__bases__# 類全部父類構成的元組(在講繼承時會講)
類名.__dict__# 類的字典屬性
類名.__module__# 類定義所在的模塊
類名.__class__# 實例對應的類(僅新式類中)

4. 對象

4.1 初識對象

人除了走路以外,還應該具有吃的功能。

class Person:  # 定義一我的類
  role = 'person'  # 人的角色屬性都是人

  def __init__(self, name, age, gender):
    self.name = name  # 每個角色都有本身的暱稱;
    self.age = age  # 每個角色都有本身的攻擊力;
    self. gender= gender  # 每個角色都有本身的生命值;

  def eat(self,food):  
    # 人能夠吃食物,這裏的食物也是一個對象。
    # 人吃食物,那麼食物的數量會隨着人吃的次數而降低
    food.num -= self.num

對象是關於類而實際存在的一個例子,即實例

對象只有一種做用:屬性調用

p = Person('egon',20,'男')
print(p.name)
print(p.age)
print(p.gender)

固然了,你也能夠引用一個方法,由於方法也是一個屬性,只不過是一個相似函數的屬性,咱們也管它叫動態屬性。
引用動態屬性並非執行這個方法,要想調用方法和調用函數是同樣的,都須要在後面加上括號。

print(p.eat)

我知道在類裏說,你可能還有好多地方不能理解。那咱們就用函數來解釋一下這個類呀,對象呀究竟是個啥,你偷偷的用這個理解就行了,不要告訴別人,畢竟一萬我的眼裏就有一萬個哈姆雷特。

def Person(*args,**kwargs):
  self = {}
  def attack(self,dog):
    dog['life_value'] -= self['aggressivity']

  def __init__(name,aggressivity,life_value):
    self['name'] = name
    self['aggressivity'] = aggressivity
    self['life_value'] = life_value
    self['attack'] = attack

  __init__(*args,**kwargs)
  return self

egg = Person('egon',78,10)
print(egg['name'])

面向對象小結——定義及調用的固定模式

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   #查看對象的屬性,直接用 對象名.屬性名 便可
對象名.方法名()     #調用類中的方法,直接用 對象名.方法名() 便可

4.2 對象之間的交互

如今咱們已經有一我的類了,經過給人類一些具體的屬性咱們就能夠拿到一個實實在在的人。
如今咱們要再建立一個狗類,狗就不能打人了,只能咬人,因此咱們給狗一個bite方法。
有了狗類,咱們還要實例化一隻實實在在的狗出來。
而後人和狗就能夠打架了。如今咱們就來讓他們打一架吧!

4.2.1 建立一個狗類和人類

class Dog:  # 定義一個狗類
  role = 'dog'  # 狗的角色屬性都是狗

  def __init__(self, name, breed, aggressivity, life_value):
    self.name = name  # 每一隻狗都有本身的暱稱;
    self.breed = breed  # 每一隻狗都有本身的品種;
    self.aggressivity = aggressivity  # 每一隻狗都有本身的攻擊力;
    self.life_value = life_value  # 每一隻狗都有本身的生命值;

  def bite(self,people):
    # 狗能夠咬人,這裏的狗也是一個對象。
    # 狗咬人,那麼人的生命值就會根據狗的攻擊力而降低
    dog.life_value -= self.aggressivit
class Person:  # 定義一我的類
  role = 'person'  # 人的角色屬性都是人

  def __init__(self, name, aggressivity, life_value):
    self.name = name  # 每個角色都有本身的暱稱;
    self.aggressivity = aggressivity  # 每個角色都有本身的攻擊力;
    self.life_value = life_value  # 每個角色都有本身的生命值;

  def attack(self,dog):  
    # 人能夠攻擊狗,這裏的狗也是一個對象。
    # 人攻擊狗,那麼狗的生命值就會根據人的攻擊力而降低
    dog.life_value -= self.aggressivity

4.2.2 實例化一隻狗和人

wc = Dog('旺財','中華田園犬',10,1000)  #創造了一隻實實在在的狗wc
xhh = Person('小灰灰',20,10000) #創造了一個實實在在的人xhh

4.2.3 交互egon打wc一下

print(wc.life_value)         #看看wc的生命值
xhh.attack(wc)               #xhh打了wc一下
print(wc.life_value)         #wc掉了20點血

4.3 類命名空間與對象、實例的命名空間

建立一個類就會建立一個類的名稱空間,用來存儲類中定義的全部名字,這些名字稱爲類的屬性

而類有兩種屬性:靜態屬性和動態屬性

  • 靜態屬性就是直接在類中定義的變量

  • 動態屬性就是定義在類中的方法

4.3.1 其中類的數據屬性是共享給全部對象的

>>>id(egg.role)
4341594072
>>>id(Person.role)
4341594072

4.3.2 而類的動態屬性是綁定到全部對象的

>>>egg.attack
<bound method Person.attack of <__main__.Person object at 0x101285860>>
>>>Person.attack
<function Person.attack at 0x10127abf8> 

建立一個對象/實例就會建立一個對象/實例的名稱空間,存放對象/實例的名字,稱爲對象/實例的屬性

在obj.name會先從obj本身的名稱空間裏找name,找不到則去類中找,類也找不到就找父類...最後都找不到就拋出異常。

相關文章
相關標籤/搜索