python基礎之面向對象編程

面向對象編程思想

  • 面向對象是一門編程思想,編程思想僅僅是一門思想,與任何技術無關
  • 核心是對象兩字,對象能夠理解爲特徵與技能的結合體
  • 基於該編程思想編寫程序,就比如創造世界,一種造物主的思惟方式
  • 優勢:可擴張性強
  • 缺點:編寫程序的複雜難度比面向過程高

以上都是純理論,理解下用本身的話能編出來就行,下面來講說核心對象python

在現實世界中,經過一個個的對象,根據相同的特徵和行爲,再分門別類。編程

可是在程序中,必須先有類,再經過調用類,建立對象函數

那麼,我們如何定義類,又如何建立對象呢?(暫時仍是先說理論吧,否則看代碼,估計直接懵逼了……)學習


關於類的致命三問:什麼是類?有什麼用?怎麼使用?code

  • 類的定義:就是類型、類別,跟現實的分類相似。是一系列對象之間相同特徵和行爲(技能)的結合體對象

  • 類的做用:我的理解,就是爲了建立對象用的。blog

(終於要寫代碼了,哈哈哈哈哈哈哈)內存

  • 類的語法
class 類名:
    特徵  # 在python 中,用變量來表示特徵
    行爲  # 在python 中,用函數來表示行爲,也就是你們所說的技能

如今,咱們來寫一我的類,人類的特徵有名字年齡性別,行爲有吃飯跑步,擼代碼了!it

"""
人類
    特徵:名字、年齡、性別
    行爲:吃飯、跑、玩
"""
class Person:
    # 這些都是人的特徵
    name = "dawn"  # 姓名
    age = 27  # 年齡
    sex = "男"  # 性別

    # 這些都是人的行爲(技能)
    def eat(self):
        # 吃飯
        print("民以食爲天o(∩_∩)o 哈哈")

    def run(self):
        # 跑步
        print("英雄救美,不存在的!別慫!趕忙跑!!!")

    def play(self):
        # 玩
        print("大爺!歡迎下次來玩兒啊!")
        
print(Person)        
print(Person.name)
print(Person.play)

輸出結果io

<class '__main__.Person'>       # Person 的打印結果
dawn            # Person.name 的打印結果
<function Person.play at 0x0000022E54FA7DC8>  # Person.play 的打印結果

瞅了這麼久,發現了嗎?類名,類的行爲,類的屬性都是咋用的?(理論又來了~~~)

  • 類名的命名規範:使用駝峯命名法,即單詞的首字母得大寫!
  • 類提供了一種便捷的獲取名字的方式,就是類名.名字。類的名字包含特徵和行爲。我們將類的特徵稱之爲屬性,類的行爲稱之爲方法
  • 在類的內部定義函數(也就是行爲的時候,默認有一個參數self),這個是幹啥的,等會說

經過輸出的內容來看,類名指向的是類的內存地址。如何來查看類的名稱空間呢?看代碼……

print(Person.__dict__)

輸出結果

{'__module__': '__main__', 'name': 'dawn', 'age': 27, 'sex': '男', 'eat': <function Person.eat at 0x00000228C1683558>, 'run': <function Person.run at 0x00000228C1683B88>, 'play': <function Person.play at 0x00000228C1687DC8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

驚不驚喜!意不意外!對,這就是Person類的名稱空間中的內容!!!也就是說類的名稱空間是在定義階段產生

到這裏,我們就該聊聊類是如何使用的了。前面咱就說了,類的調用就是對象的建立。說的類的使用就得知道對象是啥了!耐心點,好玩的還在後面!


哈哈哈哈哈!我三連問回來啦!——什麼是對象?有什麼用?怎麼使用?

  • 對象的定義特徵與技能的結合體

  • 語法類名()

我們來瞅瞅對象是如何建立的,類又是如何調用的 !

# 上面咱定義了一個Person類,這裏直接拿來用
# 調用Person類後會產生一個對象,使用一個變量接收
p1 = Person()

# 輸出p1 的屬性
print(p1.name, p1.age, p1.sex)

# 使用p1 的方法
p1.play()
p1.run()
p1.eat()

輸出結果

dawn 27 男   # p1的屬性
大爺!歡迎下次來玩兒啊!    # p1.play()的結果
英雄救美,不存在的!別慫!趕忙跑!!!  # p1.run()的結果
民以食爲天o(∩_∩)o 哈哈   # p1.eat()的結果

剛剛獲取了對象的屬性(也就是查詢),發現沒有,這些屬性都是類的,咱們可否對對象的屬性作個增刪改呢?若是修改了對象的屬性,類是否隨之改變呢?動手試試

修改對象的屬性,其實就是對象本身增長了屬性

# 修改屬性
print(Person.__dict__)  # 修改前,Person的名稱空間
print(p1.__dict__)      # 修改前,p1的名稱空間
p1.name = "haha"        # 修改對象的name 屬性,其實是p1對象本身新增了name 屬性
print(Person.__dict__)   # 修改後,Person的名稱空間
print(p1.__dict__)      # 修改後,p1的名稱空間

輸出結果

增長對象的屬性

# 增長屬性
print(p1.__dict__)
print(Person.__dict__)
p1.hobby = "read"
print(p1.__dict__)
print(Person.__dict__)

輸出結果

刪除對象的屬性

# 刪除屬性
del p1.sex
print(p1.sex)
print(Person.__dict__)

輸出結果

縱觀以上的結果,咱說了那些屬性都在類的名稱空間裏,那麼有沒有什麼方法,讓這些屬性是經過對象來增刪改查的呢?

固然有的啦!那就是__init__() !咱們來看看使用方式

# 定義一個類
class Person:
    # 這些都是人的特徵
    name = "dawn"  # 姓名

    # __init__()
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    # 這些都是人的行爲(技能)
    def eat(self):
        # 吃飯
        print("民以食爲天o(∩_∩)o 哈哈")


# 經過類建立兩個對象,分別是p1和p2
p1 = Person("haha", 39, "男")
p2 = Person("lee", 21, "女")

# 查看Person類的名稱空間
print(Person.__dict__)
# 查看對象p1的名稱空間
print(p1.__dict__)
# 查看對象p2的名稱空間
print(p2.__dict__)

輸出結果

發現什麼了沒有?

__init__()實現了對象的個性化定製,並且建立對象在傳參時,沒有傳self這個參數。

那是由於__init__()在調用時,會將對象自己做爲第一個參數傳入。緣由後期學習之後,才知道。如今就作一個總結好了

  • 由對象來調用類的內部函數,稱爲對象的綁定方法。對象的綁定方法特殊之處在於:會將對象自己看成第一個參數傳入方法(咱能夠回頭看看定義類的時候,是否是每一個行爲也就是方法,都有self參數)
  • __init__() 在調用類時觸發,會作如下事情:
    • 將對象自己看成第一個參數傳入方法(緣由:對象的綁定方法)
    • 調用時,傳入的其餘參數一併被 __init__() 接收

接着,咱們來看看,對象是如何對屬性作增刪改查的

# 獲取p1的屬性
print(f"姓名:{p1.name},性別:{p1.sex},年齡:{p1.age}")

# 修改p1的屬性
print(f"修改前,p1的名稱空間:{p1.__dict__}")
p1.age = 27
print(f"修改後,p1的屬性值:{p1.age}")
print(f"修改後,p1的名稱空間:{p1.__dict__}")

輸出結果

再來看看增長(前面就已經舉例了,算了仍是再舉一個吧)和刪除

# 獲取p1的屬性
print(f"姓名:{p1.name},性別:{p1.sex},年齡:{p1.age}")

# 增長屬性
print(f"增長hobby前:{p1.__dict__}")
p1.hobby = "read"
print(f"hobby的取值:{p1.hobby}")
print(f"增長hobby後:{p1.__dict__}")


# 刪除屬性
print(f"刪除sex前:{p1.__dict__}")
del p1.sex
print(f"刪除sex後:{p1.__dict__}")

輸入結果

還有個地方,就是咱剛纔一直在說名稱空間,那麼類的名稱空間和對象的名稱空間,有什麼關係呢?

我們繼續看代碼

# 經過類建立一個對象
p1 = Person("haha", 39, "男")

# 查看Person類的名稱空間和屬性
print(f"Person的名稱空間:{Person.__dict__}")
print(f"Person的name屬性值:{Person.name}")
# 查看對象p1的名稱空間和屬性
print(f"p1的名稱空間:{p1.__dict__}")
print(f"p1的name屬性值:{p1.name}")

# 刪除p1的屬性name,再打印p1的名稱空間和屬性
del p1.name
print(f"刪除name屬性後,p1的名稱空間:{p1.__dict__}")
print(f"刪除name屬性後,p1的name屬性值:{p1.name}")

輸出結果

看到沒?對象的屬性刪除後,再去調用這個屬性,並無報錯,而是將類中的同名屬性值獲取了過來

那若是類中沒有這個屬性呢?咱們再來看看

class Person:
    # 這些都是人的特徵
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

# 經過類建立一個對象
p1 = Person("haha", 39, "男")
# 查看對象p1的名稱空間和屬性
print(f"p1的名稱空間:{p1.__dict__}")
print(f"p1的name屬性值:{p1.name}")
# 刪除p1的屬性name,再打印p1的名稱空間和屬性
del p1.name
print(f"刪除name屬性後,p1的名稱空間:{p1.__dict__}")
print(f"刪除name屬性後,p1的name屬性值:{p1.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   #查看對象的屬性,直接用 對象名.屬性名 便可
對象名.方法名()     #調用類中的方法,直接用 對象名.方法名() 便可
相關文章
相關標籤/搜索