iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 15
0
Software Development

python 自學系列 第 15

python day15 (classes)

  • 分享至 

  • xImage
  •  

在寫程式的風格裡有分為物件導向、函數式導向、程序性導向三種風格.物件在物件導向程式設計是很重要的一環,物件有自身的狀態以及方法.而 classes 就是定義這些狀態(屬性)跟方法,而物件就是 classes 實體化後的 instance.
用 type 可以看這個'Python'這個 string 物件是哪個 class 實體化的.

>>> type('Python')
<class 'str'>

當要定義一個 class 時要思考,要定義 class 的名稱、有哪些屬性以及提供哪些方法.

使用 class 關鍵字定義一個 class.和定義 class 的方法,在 class 的方法裡第一個參數要給一個 self,表示該 instance.

>>> class Animal:
...  def move(self,action):
...   print('{}'.format(action))
...

定義好後,透過建構子把 Animal 實體化,變成一個 instance 也就是物件,然後透過 a1 這變數指到該物件.

>>> a1 = Animal()

接著就可以使用該物件的方法.

>>> a1.move('running')
running
>>> a1.move('flying')
flying

上面的寫法其實相當於這樣寫,a1 也就是 self 該 instance.

>>> Animal.move(a1,'jump')
jump

其實不一定要叫 self,改成其它的名稱也是可以,但為了可讀性還是統一使用 self 比較好.

>>> class Animal:
...  def move(test_self,action):
...   print('{}'.format(action))
...
>>> a1 = Animal()
>>> a1.move('flying')
flying

接著幫 Animal 定義屬性,定義__init__這 function 讓在實體化時多給個參數 name,再把這個參數帶到 self 的 name 裡.__init__稱為建構子,可以設定一些產生物件時需要先初始化的一些過程.

>>> class Animal:
...  def __init__(self,name):
...   self.name = name
...  def move(self,action):
...   print('{} is {}'.format(self.name , action))
...
>>> a1 = Animal('Dog')
>>> a1.move('running')
Dog is running
>>> a1.name
'Dog'

使用 dir 看 Animal 個 class 並沒有 name 這屬性.

>>> dir(Animal)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'move']

但看 a1 這物件可以多看到一個 name 屬性.

>>> dir(a1)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'move', 'name']

所以 name 屬於實體屬性,只有實體才能使用到,另外還有一種是類別屬性.類別屬性跟方法一樣定義在 class 的下一層.例如下面的 age 屬性.
然後在使用類別屬性時要加上類別名稱

>>> class Animal:
...  age = 0
...  def __init__(self,name):
...   self.name = name
...  def add_age(self,new_age):
...   Animal.age = new_age
...  def pring_age(self):
...   print(Animal.age)
...

類別屬性會影響到所有用該類別創建的 instance 也就是物件,只要類別屬性的值改變,每個 instance 都會更新.

>>> a1 = Animal('Cat')
>>> a1.add_age(5)
>>> a1.pring_age()
5
>>> a2 = Animal('Dog')
>>> a2.pring_age()
5
>>> Animal.age
5
>>> Animal.age = 10
>>> a1.pring_age()
10
>>> a2.pring_age()
10

存取類別屬性也可以用cls.使用的方式跟self有點像,也是第一個參數,只不過 cls 指的就不是實體了,而是該類別.

>>> class Animal:
...  age = 0
...  def __init__(self,name):
...   self.name = name
...  def add_age(cls,new_age):
...   cls.age = new_age
...  def pring_age(cls):
...   print(cls.age)
...
>>> a1 = Animal('Cat')
>>> Animal.age = 5
>>> a1.pring_age()
5
>>> a2 = Animal('Dog')
>>> a2.pring_age()
5

python 再找屬性時會先從物件屬性開始找,找不到再找類別屬性,所以可以透過物件找到類別屬性,如果都找不到就會出現 AttributeError.

>>> Animal.age
10
>>> a2.age
10
>>> a2.aaa
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Animal' object has no attribute 'aaa'

屬性實際上的值其實是存在__dict__這 dictionary 裡.可以看到一開始類別屬性 age 並沒有存在裡面,當改變了 age 的值,就會存到__dict__

>>> class Animal:
...  age = 0
...  def __init__(self,name):
...   self.name = name
...  def add_age(cls,new_age):
...   cls.age = new_age
...  def pring_age(cls):
...   print(cls.age)
...
>>> a1 = Animal('Cat')
>>> type(a1.__dict__)
<class 'dict'>
>>> a1.__dict__
{'name': 'Cat'}
>>> a1.add_age(5)
>>> a1.__dict__
{'name': 'Cat', 'age': 5}

在 python 幾乎都是物件,所以都會有個__class__屬性,可以看到參考的類別.

>>> ''.__class__
<class 'str'>
>>> Animal.__class__
<class 'type'>
>>> a1.__class__
<class '__main__.Animal'>
>>> type(a1.__class__)
<class 'type'>

上一篇
python day14 (File Input、Output)
下一篇
python day16 (private、underscore)
系列文
python 自學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言