iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0
自我挑戰組

從前端角度看30天學Python系列 第 24

【Day 24】類別與物件

  • 分享至 

  • xImage
  •  
  • 創造一個類別
    • 用類別產生一個物件
  • 類別建構子
  • 物件方法
  • 繼承

這篇文章是閱讀Asabeneh的30 Days Of Python: Day 21 - Classes and Objects後的學習筆記與心得。


Python 是物件導向語言,所有的東西在 Python 中都是一個物件 (object),並有自己的屬性 (properties) 與方法 (methods)。

  • number, string, list, dictionary, tuple, set 等都是內建的類別(classes)
  • 我們能透過創造一個 class 來 創造一個新的物件,class 就像是 物件的建構子 (constructor),或稱藍圖 (blueprint)。

在 JavaScript 中所有東西就只是物件 (object),連 class 也是物件做出來的。constructor 則是產生物件的方法 (method)。

可以用 type() 這個函式來看到物件型別的 class:

num = 10
print(type(num)) # <class 'int'>

創造一個類別

與 JavaScript (以下簡稱JS)差不多,命名部分要使用 CamelCase:

class PersonInfo:
    pass
    
print(PersonInfo) # <class '__main__.PersonInfo'>

用類別產生一個物件

然後可以透過呼叫剛剛創造的 class 來得到一個物件:

p = PersonInfo()
print(p)
# <__main__.PersonInfo object at 0x000001CB0617EF20>

類別建構子

就像 JS 的 class 可以透過定義 constructor 屬性給 class 增加繼承後物件會拿到的屬性一樣,Python 中透過定義 __init__(self,[, ...]) 能做到一樣的事:

class PersonInfo:
    def __init__ (self, name, city):
        self.name = name
        self.city = city

p = PersonInfo("John", "Taipei")
print(p.name) # 'John'
print(p.city) # 'Taipei'

物件方法

這裡也像 JS,我們可以在 class 中撰寫函式,透過這個 class 產生的物件就能在屬性中發現,並呼叫這些函式:

class PersonInfo:
    def __init__(self, name="John", city="Taipei"):
        self.name = name
        self.city = city
    def set_name(self):
        self.name = input("Please enter your name: ")
        return f"Your new name is: {self.name}"

p = PersonInfo("Wilson", "Taichung")
print(p.set_name())
# Please enter your name: Mary
# Your new name is: Mary

p2 = PersonInfo()
print(f"Hi {p2.name} from {p2.city}!")
# Hi John from Taipei!
  • 可以給 __init__ 參數一個預設值,在像 p2 這樣沒有給定參數的建構時就不會產生 TypeError;當然這取決於開發者的需求。
  • 就像 __init__ 中有 self 指到產生的物件本身,額外我們放進去的函式也能這樣使用,像 set_name 就透過這種方式來修改物件內的屬性。

繼承

JS 中要繼承類別需要使用 extends keyword,Python 不太一樣,是把要繼承的類別當參數放進子類別中,另外有幾個點要先說明:

  1. 在子類別沒有定義 __init__ 的情況下,會自動沿用母類別的屬性。
  2. 若子類別有定義 __init__,則會覆寫掉母類別的屬性(無法呼叫到)
  3. 在第2點的情況下想要留下母類別的屬性,可以使用 super() 函式,可參考下方例子用法。
  4. 物件繼承時,會優先呼叫子類別有定義的屬性和方法,若子類別沒有才會向上查找母類別。
class PersonInfo:
    def __init__(self, name="John", city="Taipei"):
        self.name = name
        self.city = city
    def set_name(self):
        self.name = input("Please enter your name: ")
        return f"Your new name is: {self.name}"
    def get_info(self):
        return {"name": self.name, "city": self.city}
  

class Student(PersonInfo):
    def __init__(self, name="unregistered", city="unknown", course="unsigned"):
        super().__init__(name, city)
        self.course = course
    def get_info(self):
        return {"course": self.course}


p = Student("Wilson", "Taichung", "30 days of Python")
print(p.get_info())
# {'course': '30 days of Python'}


p2 = Student()
print(f"Hi {p2.name} from {p2.city}!")
# Hi unregistered from unknown!
  • 這邊可以看到 Student(PersonInfo)就是 Studnet 這個類別繼承了 PersonInfo 這個類別。
  • 然後 Student 內有自己的 __init__,這裡面又 super,並把接收到的namecity參數放進引數中給 PersonInfo
  • p 物件呼叫 get_info() 方法,從回傳結果可以看出是拿到 Studentget_info() 而不是 PersonInfo 的—對應到上方第4點。
  • p2 物件呼叫 namecityStudent 類別中並沒有定義這些屬性,因此會拿到母類別,也就是 PersonInfo 的屬性。

上一篇
【Day 23】Python 套件管理
下一篇
【Day 25】網頁抓取
系列文
從前端角度看30天學Python30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言