Class

簡單來說,class 就是自己寫的 type

之前稍微提到「物件導向」這個概念過,那時候我們說 in Python, everything is an object,而物件導向另一個主要的必要條件就是 we create objects,而這個 object 就是 class。(畢竟物件導向就叫 Object-oriented programming)
判斷一個程式語言是不是物件導向就可以用它有沒有 class 來粗略區分。

從之前遇過的各種 type 的經驗,可以總結出 class 常見的內容物有 value 跟 function。
Value 就像是之前用過的 turtle 有 color 或 shape 這些可微調事項,而 function 就像 turtle 可以 .up(), .down(), .goto() 的指令。

__init__

下面是一個經典的 class

class Person:
    def __init__(self):
        self.name = ""
        self.age = 0
        self.id = 0

def __init__(self): 幾乎是 class 不可或缺的 function,括號內的 argument self 也是固定用法,指這一個 class 本人。
同時這也是一個 magic method,也就是不用被叫就會執行的 function。在有人用 a = Person() 創造一個新的 person object 時,init 就會自動被叫,也只會在一個 object 被創造時跑這一次。

裡面 self.name = "" 是把 empty string "" 塞到 self.name 裡面。self 剛剛說是這個 class 本人的代稱,所以 name 就是這個 class 的其中一個 variable 了。

當一個 Person object 被創造時,它的 name 預設為 empty string、age 預設為 0、id 也預設為零。

接著在這段程式底下加上這些:

def main():
    p1 = Person()
    p2 = Person()

    print(p1.age)
    print(p2.age)

main()

就像宣告了兩個 int 一樣,我們宣告了兩個變數,p1 和 p2,這兩個變數的 type 都是 Person,也有各自的 name, age, 和 id。
這些 variable 的取得方式就跟 datetime.datetime 一樣,透過點來一層一層進入。

接著把 main() 換成:

def main():
    p1 = Person()
    p2 = Person()

    p1.age = 10

    print(p1.age)
    print(p2.age)

main()

由此可知, class 像一個模板,每一個用其製作出來的物件都是獨立的。

Member functions

接著我們繼續擴充

class Person:
    def __init__(self):
        self.name = ""
        self.age = 0
        self.id = 0

    def create_intro(self, lines=""):
        intro = "Hi my name is " + self.name + ", I am " + str(self.age) + " years old, my id is " + str(self.id) + " " + lines
        return intro

create_intro 是一個隸屬於 Person class 的 function,只要一個 member function 需要用到這個 class 的 variable,就需要把 self 當作其中一個 argument。
第二個 argument 是 lines,後面的等於 empty string 代表預設。
試試下面的 main():

def main():
    p1 = Person()
    p2 = Person()

    p1.name = "alex"
    p1.age = 10
    p1.id = 123

    p2.name = "steve"
    p2.age = 50
    p2.id = 456

    print(p1.create_intro("nice to meet you!"))
    print(p2.create_intro())

main()



這就是 class 的概念,最重要的是面對一個情境時,哪些東西可以用 class?裡面又該放什麼 variable 和 function。
像是之前介紹的 json 格式是很好的儲存資料形式,但當一個龐大的程式在運行時,如果把 dict 變成一個 class 呢,讓 list of dicts 變成 list of objects 會不會比較好呢?



Additional Readings
  1. Classes and Objects - the Basics https://runestone.academy/ns/books/published/thinkcspy/ClassesBasics/toctree.html