關於Python的類別(Class)...基本篇

張凱喬
7 min readAug 23, 2017

我覺得Class是Python速成班最重要的一環
因為一般我們在寫Python時
一定會用到模組(package)

而模組為了有架構的呈現功能
一定是好由幾個py檔組成
這些py檔裡面再用class及def結構化

所以class跟def是組成模組功能的最低架構
這邊用三個簡單實例 先帶大家認識一下class類別

class類別,就是像一個模組,可以產出具有相似特性的實體(物件)
也有人會說他像是一個蛋糕模子,可以一直套用 生產蛋糕

底下我們會舉動物的例子
他們都會有相同的"屬性"、不同的"參數"

譬如,他們都會有"名字"、"物種"的屬性
每隻動物對應到這個屬性都會有一個特殊的值("參數")
第一隻動物是名叫"Nico"(名字)的"狗"(物種)
第二隻動物是名叫"Nana"(名字)的"貓"(物種)

所以我有一個可以套用的類別
就可以產生無限多隻動物,他們則都有自己的屬性參數

在python裡,就是用class 開宗明義定義一個類別名稱
通常會用首字大寫的單字

簡單範例1:建立基本屬性

class Animal():
def __init__(self, name):
self.name = name
a = Animal("dog") #建立一個名叫dog的Animal實體(物件)
print(a.name)

用Animal開啟一個類別
代表之後的大家都可以取用這個類別的設定
達到避免重複設定函式的目的

def __init__(self):
這邊代表宣告時會自動執行的函式
也就是宣告類別的"起手式"
所以一般會拿來放基礎的屬性設定

如上面的簡單範例1,在起手式添加了一個name屬性
所以在創造實體時,都必須要給這個屬性一個參數
才能成功創造實體

補充說明
class的概念是屬性集合,而不是所有物
譬如說 上面的範例是 動物.名字
意思是 名字是動物的屬性
所以你不能用 王大明.鉛筆 來解釋class的概念
因為鉛筆不是王大明的屬性 他只是王大明的所有物

#上面不懂的話我再補充一個舉例譬如狗的話 你可以新增他的類別
class Dog():
屬性則是名字、年齡、血型、喜歡的食物等
可以這樣加入屬性
這邊用中文闡述def __init__的過程
def __init__(self,名字,年齡)
因為self是class本身 所以第一個不用更動
接下來再設定
self.名字=名字
self.年齡=年齡
在這邊self.的設定 就代表你之後可以用的class屬性
所以我之後就可以用
來福 = Dog(來福,8)
讓來福變成是一種dog類別的物件
並且具有名字屬性跟年齡屬性 所以
print 來福.年齡 就會出現8

簡單範例2:取用自己的屬性

class Animal():
def __init__(self, name):
self.name = name
def who(self):
return self.name
a = Animal(dog)
print a.who #-> dog

沒有甚麼特別的,只是要注意使用函式def 跟 屬性時
要在位置上加上self,這樣子呼叫函式時才會運作正常

有一個特別的是
如果變數不希望直接被取用
則可以給兩條底線 例如 self.__name

class Animal():
def __init__(self, name):
self.__name = name
a = Animal(dog)
print a.__name #raise error

這時候就會產生錯誤,因為__name不能直接讀取
可以用來設定一些內部使用的函數
(但不能保證外部無法讀取,只是必須透過一些迂迴方式)

簡單範例3:互動案例-存款與取款

class Account:
def __init__(self, number, name):
self.number = number
self.name = name
self.balance = 0

def deposit(self, amount): #存款動作: amount代表存入金額
if amount <= 0:
raise ValueError('must be positive')
self.balance += amount

def withdraw(self, amount): #取款動作: amount代表取款金額
if amount <= self.balance:
self.balance -= amount
else:
raise RuntimeError('balance not enough')

這邊的簡單例子,便是創造一個銀行戶頭
然後銀行戶頭可以進行存款與取款的互動

定義完class之後,就可以寫一些存取款動作

acct1 = Account(‘123–456–789’, ‘Justin’) #開一個帳戶acct1.deposit(100)
acct1.withdraw(30)
print(acct1.balance) #餘額是 70

這邊補充一些__init__起手式的概念

重要概念一: 用__init__設定可以有些變化

class Animal():
def __init__(self, name):
self.name = name
a = Animal("dog")
print(a.name)

延續簡單範例1,此時如果呼叫 b=Animal()
就會出錯,因為你沒有給他name的屬性

class Animal():
def __init__(self, name=default):
self.name = name
a = Animal(‘動物’)
print(a.name)

可以先給一個預設值,這樣第一次呼叫就不用給屬性
如果是固定的值,呼叫時也不用給了,直接設定就好

class Animal():
def __init__(self):
self.password = 123456
a = Animal()

當然,也是可以是空的,之後再新增資料就好

class Animal():
def __init__(self):
self.data = []
a = Animal()
a.data.append(123456)

重要概念二: __init__並不是必要的

簡單來說,python class自由度很高

你也可以這樣,直接給屬性,不透過__init__

class Animal():
name="dog" #把參數寫在init外面
def __init__(self):
pass
a = Animal()
print a.name

需要屬性時,我不見得一定要在init裡設定
也不見得一定要在class裡設定,就像下面這樣

class Animal():
def __init__(self):
pass
a = Animal()
a.name="dog" #自己給屬性與參數
print a.name

可以在使用Animal這個類別之後,再自己新增屬性

--

--