iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
Software Development

闖進Python異世界系列 第 12

[Day 12] 闖進Python異世界 - Class 屬性 - 實戰開模 Part 1/2

  • 分享至 

  • xImage
  •  

今天來做一個 class Student 吧!

接續上一篇的問題:
他所生產出的物件需要有什麼特性、行為?

姓名、體重、成績、興趣應該算是他們的特性吧!
行為呢?讀書、吃飯、運動是學生們正常的行為。

要怎麼表達,學生的特性與行為呢?

  • 特性會被定義在建構子(constructor)中。
  • 行為會以函式呈現。

建構子

先來處理特性的部分!

class Student:
    def __init__(self):
        self.name = "Bob"
        self.weight = 50
        self.gpa = 3.6
        self.hobby = ['play baseball', 'watch movie']

測試看看,Student產生出的物件是不是都有姓名、體重、成績、興趣這些特性

Bob = Student()
print(f"Bob's name = {Bob.name}")
print(f"Bob's weight = {Bob.weight}")
print(f"Bob's gpa = {Bob.gpa}")
print("Bob's hobby = ", end = "")
for hobby in Bob.hobby:
    print(hobby, end = " ")

一切正常,那我們再做一個物件

John = Student()
print(f"John's name = {John.name}")
print(f"John's weight = {John.weight}")
print(f"John's gpa = {John.gpa}")
print(f"John's hobby = {', '.join(John.hobby)}")

欸?John 是不是拿到 Bob 的學生證?還是John是複製人?
不是啦~原因是我們沒有做到客製化!

客製化建構子

建構子後方在多給幾個參數!

class Student:
    def __init__(self, name, weight, gpa, hobby):
        self.name = name
        self.weight = weight
        self.gpa = gpa
        self.hobby = hobby

再來測試看看吧!

John = Student("John", 65, 2.5, ['sing', 'dance'])
print(f"John's name = {John.name}")
print(f"John's weight = {John.weight}")
print(f"John's gpa = {John.gpa}")
print(f"John's hobby = {', '.join(John.hobby)}")

搞定啦!

不過,我們稍微再升級一下!

與其傳入一個列表,不如傳入 *hobbies ,因為我們並不知道這個學生到底有多少興趣。
相較傳入列表來說,這種方式比較常見。

class Student:
    def __init__(self, name, weight, gpa, *hobbies):
        self.name = name
        self.weight = weight
        self.gpa = gpa
        self.hobby = []
        for hobby in hobbies:
          self.hobby.append(hobby)

宣告 Student 的物件,從第四個參數開始都是學生興趣。

John = Student('John', 67, 3.8, 'sleep', 'eat')

self 關鍵字

不知道你沒有發現「建構子定義式中的參數」永遠比「使用建構子需傳入的參數」多一個?

def __init__(self, name, weight, gpa, hobby): # 5 parameters
John = Student("John", 65, 2.5, ['sing', 'dance']) # 4 arguments
def __init__(self): # 1 parameter
John = Student() # 0 argument

這一個差距就是 self 關鍵字!
簡單來說,self 就是代表物件本身。

如果學過 C++, JavaScript ,你可能會見過代表物件自己的 this 關鍵字
Python 中,我們使用 self
self this 的功能其實是相同的,只是不同語言有不同的語法

證明一下,self 就是代表物件本身!

class myClass:
  def __init__(self):
    print(id(self))

obj = myClass()
print(id(obj))

這兩個輸出分別印出 id(self)id(obj)
結果兩個輸出是完全相等的,代表兩者是相同的東西


印出所有屬性

在物件的背後其實有一個變數儲存了該物件的所有屬性,而這個變數的型態是一個字典。

語法是 vars(),括號裡的參數可以是關鍵字 self 或物件名稱,用法參見以下範例!

class myClass:
    def __init__(self):
        self.name = 'Bob'
        print(vars(self))
        print('name' in vars(self))
class myClass:
    def __init__(self):
        self.name = 'Bob'
bob = myClass()
print(vars(bob))
print('name' in vars(bob))

特別注意的是屬性名稱會以字串來儲存,因此從上述的例子可以看到我們以 'name' in vars(self) 來判斷物件是否有屬性 name,而非 name in vars(self)


今天就先設定 class Student 的特性,下一次我們來讓學生有些行為!


上一篇
[Day 11] 闖進Python異世界 - Class 你會開模嗎?
下一篇
[Day 13] 闖進Python異世界 - Class 方法 - 實戰開模 Part 2/2
系列文
闖進Python異世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言