tft每日頭條

 > 圖文

 > 你需要理解的Python核心概念-對象

你需要理解的Python核心概念-對象

圖文 更新时间:2024-08-11 18:19:51

你需要理解的Python核心概念-對象(你需要理解的Python核心概念-對象)1

Python Object And Classes

對象是 Python 語言的構建塊

Python 很容易學習。然而,它有一些更難理解的方面,比如類和對象的世界。在本文中,你将學到:

  • 在 Python 中一切都是對象
  • 如何創建自己的類和對象
  • 什麼是繼承以及如何利用它來發揮自己的優勢

通過揭開 Python 對象的神秘面紗,你對該語言的理解将大大增加!

對象

對象在 Python 中起着核心作用。讓我們深入了解一下,以增加你對對象的理解。

你可能知道内置len函數。它返回你給它的對象的長度。但是,比如說,數字5 的長度是多少?讓我們運行一下代碼看看。

print(len(5))

我喜歡錯誤,因為它們說明了 Python 内部是如何工作的。在這種情況下,Python 告訴我們 5 是一個對象,它沒有len().

在 Python 中,一切都是對象。字符串、布爾值、數字,甚至函數都是對象。

我們可以使用内置函數檢查 REPL 中的對象dir()。當我們嘗試dir使用數字 5 時,它會顯示一個很大的函數列表,這些函數是任何數字對象的一部分

dir(5)

你需要理解的Python核心概念-對象(你需要理解的Python核心概念-對象)2

該列表以這些包含下劃線的奇怪命名函數開頭,例如__add__. 這些被稱為魔術方法,或 dunder(雙下劃線的縮寫)方法。

如果你仔細觀察,你會發現類型對象沒有__len__dunder 方法int。這就是 Python 的len()函數如何知道數字沒有長度的方式。len()所做的就是調用你提供的對象上的方法__len__()。這也是 Python 抱怨 'int' 類型的對象沒有len().

我在這裡随便介紹了方法這個詞。讓我更正式地定義它:

當函數是對象的一部分時,我們稱其為方法。

所以如果一個字符串确實有長度,它一定有一個__len__方法,對吧?讓我們來了解一下!

dir("test")

你需要理解的Python核心概念-對象(你需要理解的Python核心概念-對象)3

可以看到字符串有__len__()這個方法。由于這是一個方法,我們也可以調用它:

"test".__len__() # 4

這相當于len("test"),但不那麼優雅。所以不要這樣做,這隻是為了說明這些東西是如何工作的。

還有一系列其他不那麼神奇的方法dir()向我們揭示了。随意嘗試一些,例如

"test".islower() # true

此方法檢查整個字符串是否為小寫,因此 Python 返回 boolean True。其中一些方法需要一個或多個參數,例如replace:

"abcd".replace('a','b') # 它将所有出現的“a”替換為“b”。 # 'bbcd'

什麼是對象

現在我們已經使用了對象并且知道 Python 中的一切都是對象,是時候定義對象是什麼了:

對象是數據(變量)和對該數據進行操作的方法的集合

對象和面向對象編程是 1990 年代初流行的概念。早期的計算機語言,如 C,沒有對象的概念。然而,事實證明,對象對于人類來說是一種易于理解的範式——它可以用來模拟許多現實生活中的情況。

如今,大多數(如果不是全部)新語言都有對象的概念。因此,你将要學習的内容在概念上也适用于其他語言。

由于對象是 Python 語言的構建塊,因此你也可以自己創建對象是合乎邏輯的。為此,我們需要先定義一個類。

class

如果要創建自己的對象類型,首先需要定義它具有哪些方法以及它可以保存哪些數據。這個藍圖被稱為一個類

類是對象的藍圖

所有對象都基于一個類。當我們創建一個對象時,我們稱之為“創建一個類的實例”。字符串、數字甚至布爾值也是類的實例。讓我們用内置函數來探索type:

>>> type('a') <class 'str'> >>> type(1) <class 'int'> type(True) <class 'bool'>

顯然我們看到一些有名為str、int和的類bool。這些是 Python 的一些原生類,但我們也可以構建自己的類!

讓我們創建一個代表汽車的類。

class Car: speed = 0 started = False def start(self): self.started = True print("Car started, let's ride!") def increase_speed(self, delta): if self.started: self.speed = self. speed delta print('Vrooooom!') else: print("你需要先啟動汽車") def stop(self): self.speed = 0 print('Halting')

讓我們首先創建并使用一個 Car 類型的對象

car = Car() car.increase_speed(10) car.start() car.increase_speed(40)

你需要理解的Python核心概念-對象(你需要理解的Python核心概念-對象)4

對象始終是類的實例。一個類可以有多個實例。我們剛剛創建了一個 Car 類的實例,使用Car(),并将其分配給變量car。創建一個實例看起來就像調用一個函數——你稍後會知道為什麼。

接下來,我們在汽車對象上調用其中一種方法:嘗試在它還沒有啟動的時候提高它的速度。哎呀!隻有啟動汽車後,我們才能提高它的速度并享受它發出的噪音。

現在讓我們逐步回顧一下我們的 Car 類:

  • 使用class後跟類名 (Car) 的語句定義類。我們用冒号開始一個縮進的代碼塊。
  • 我們定義了兩個變量,speed和started。這是該類的所有實例都将擁有的數據。
  • 接下來,我們定義了三個對變量進行操作的方法。

在這些方法的定義中,我們遇到了一些特殊的情況:它們都有一個參數,稱為self它們的第一個參數。

什麼是self?

老實說,如果你問我,這是 Python 不太優雅的語言結構之一。

還記得我們在汽車對象上調用方法的時候car.start()嗎?我們不必傳遞self變量,即使在類内部start定義start(self)。

這就是正在發生的事情:

  1. 當我們在對象上調用方法時,Python 會自動填充第一個變量,我們self按照約定調用
  2. 第一個變量是對對象本身的引用,因此它的名字
  3. 我們可以使用這個變量來引用這個對象的其他實例變量和函數,比如self.speed和self.start()。

因此,僅在類定義中,我們使用 self 來引用屬于實例一部分的變量。要修改started屬于我們類的變量,我們使用self.started而不僅僅是started.

通過使用self,可以清楚地表明我們正在對作為此實例一部分的變量進行操作,而不是在對象外部定義并且恰好具有相同名稱的其他變量。

從一個類創建多個對象

由于一個類隻是一個藍圖,你可以使用它來創建多個對象,就像你可以構建多個外觀相同的汽車一樣。它們的行為都相似,但它們都有自己的數據,而不是在對象之間共享:

>>> car1 = Car() >>> car2 = Car() >>> id(car1) 139771129539104 >>> id(car2) 139771129539160

我們在這裡創建了兩個汽車對象,car1 和 car2,并使用内置方法id()獲取它們的 id。Python 中的每個對象都有一個唯一的标識符,所以我們隻是證明了我們從同一個類中創建了兩個不同的對象。我們可以獨立使用它們:

>>> car1.start() 車子啟動了,我們騎吧! >>> car1.increase_speed(10) 'Vrooom!' >>> car1.speed 10 >>> car2.speed 0

我們剛剛開始car1并增加了它的速度,而car2的速度沒有發生改變,這就是不同的實例具有不同的狀态。

構造函數

當從一個類創建一個對象時,看起來我們正在調用一個函數:

car = car()

但它看起來不僅僅是我們在調用一個函數,我們實際上是在調用一個函數!這個我們不必定義的方法稱為構造函數。它構造并初始化對象。每個類默認都有一個,稱為__init__,即使我們自己沒有定義它。這與繼承有關,稍後我将說明這一點。

你是否曾經使用該str()函數将對象轉換為類?或者可能是 int() 函數将字符串轉換為數字?

>>> 'a' str(1) 'a1' >>> int('2') 2 4

實際上在這裡所做的是創建新的類型對象str并int通過調用類的構造函數str和int.

我們也可以重寫該__init__方法,通過接受參數來賦予它額外的能力。讓我們使用自定義構造函數重新定義 Car 類:

class Car: def __init__(self, started = False, speed = 0): self.started = started self.speed = speed def start(self): self.started = True print("Car started, let's ride!") def increase_speed(self, delta): if self.started: self.speed = self.speed delta print("Vrooooom!") else: print("你需要先啟動汽車") def stop(self): self.speed = 0

我們的自定義構造函數使用默認值命名參數,因此我們可以通過多種方式創建 Car 類的實例:

>>> c1 = Car() >>> c2 = Car(True) >>> c3 = Car(True, 50) >>> c4 = Car(started=True, speed=40)

繼承

在編程中,盡可能多地重用代碼被認為是一種很好的風格。這種做法甚至有一個很好的首字母縮寫詞,稱為 DRY:不要重複自己。

類可以幫助你避免重複代碼,因為你可以編寫一個類并基于它創建許多對象。但是,它們還以另一種方式為你提供幫助,稱為繼承。類可以從其他類繼承屬性和函數,因此你不必重複自己。

例如,我們希望我們的 Car 類從 Vehicle 類繼承一些基礎知識。而且,當我們這樣做的時候,還要定義一個 Motorcycle 類。從示意圖上看,它看起來像這樣:

你需要理解的Python核心概念-對象(你需要理解的Python核心概念-對象)5

我們已經看到了繼承的作用。還記得我告訴過你每個類都有一個構造函數(__init__),即使你沒有定義一個?這是因為每個類都繼承自 Python 中最基本的類,稱為object:

dir(object)

你需要理解的Python核心概念-對象(你需要理解的Python核心概念-對象)6

當我告訴你“Python 中的一切都是對象”時,我的意思是一切。這包括類,如你所見,我們也可以dir()在類上使用。它表明object有一個__init__方法。

繼承映射到許多現實生活中的情況。讓我們根據上圖來看看實際的繼承。我們将從一個泛型Vehicle類開始:

class Vehicle: def __init__(self, started = False, speed = 0): self.started = started self.speed = speed def start(self): self.started = True print("Started, let's ride!") def stop(self): self.speed = 0 def increase_speed(self, delta): if self.started: self.speed = self.speed delta print("Vrooooom!") else: print("You need to start me first")

現在我們可以Car使用繼承重新定義我們的類

class Car(Vehicle): trunk_open = False def open_trunk(self): trunk_open = True def close_trunk(self): trunk_open = False

我們的汽車從類中繼承了所有的方法和變量Vehicle,但是增加了一個額外的變量和兩個方法。

重寫init方法

有時你想覆蓋 init 函數。為了演示,我們可以創建一個 Motorcycle 類。大多數摩托車都有一個中心支架。我們将添加在初始化時将其輸出或輸入的功能:

class Motorcycle(Vehicle): def __init__(self, center_stand_out = False): self.center_stand_out = center_stand_out super().__init__()

當你覆蓋構造函數時,根本不會調用來自父類(我們繼承的)的構造函數。如果你仍然需要該功能,則必須自己調用它。這是通過super():它返回對父類的引用,因此我們可以調用父類的構造函數。

在這種情況下,我們為中心支架添加了功能,但删除了在構造函數中設置速度和啟動狀态的選項。如果需要,你也可以添加速度和啟動狀态選項,并将它們傳遞給Vehicle構造函數。

覆蓋其他方法

就像__init__,我們也可以覆蓋其他方法。例如,如果你想實現一個不啟動的摩托車,你可以重寫 start 方法:

class Motorcycle(Vehicle): def __init__(self, center_stand_out = False): self.center_stand_out = center_stand_out super().__init__() def start(self): print("Sorry, out of fuel!")

感謝你的閱讀。如果你想了解有關 Python 的更多信息,請關注我。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved