從turtle海龜動畫 學習 Python - 高中彈性課程系列 9 Python 物件導向介紹

“Talk is cheap. Show me the code.”
― Linus Torvalds

老子第41章
上德若谷
大白若辱
大方無隅
大器晚成
大音希聲
大象無形
道隱無名

拳打千遍, 身法自然

“There’s no shortage of remarkable ideas, what’s missing is the will to execute them.” – Seth Godin
「很棒的點子永遠不會匱乏,然而缺少的是執行點子的意志力。」—賽斯.高汀

高中彈性課程系列

本系列文章之連結

  • 從turtle海龜動畫學習Python-高中彈性課程1 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 2 安裝 Python, 線上執行 Python link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 3 烏龜繪圖 所需之Python基礎 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 4 烏龜開始畫圖 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 5 用函數封裝重複性指令-呼叫函數令烏龜畫正 n 邊形 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 6 畫多重旋轉圓,螺旋正方形 link

  • 從turtle海龜動畫 學習 Python - 7 遞歸 recursive - 高中彈性課程系列 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 8 碎形 (分形 fractal) link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 8.1 碎形 L-system link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 9 Python 物件導向介紹 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 9.1 Python 物件導向的練習 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 10 藝術畫 自定義海龜形狀 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 10.1 藝術畫 python繪製天然雪花結晶 https://blog.csdn.net/m0_47985483/article/details/122262036 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 10.2 藝術畫 Python 製作生成式藝術 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.1 氣泡排序 - 用 turtle 呈現演算法之執行動作 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.2 maze 迷宮 - 用 turtle 呈現演算法之執行動作 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.3 連分數演算法與轉轉相除法- 用 turtle 呈現演算法之執行動作 link

  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.4 最短路徑 Dijkstra- 用 turtle 呈現演算法之執行動作 link



AI Sweigart 書中建議幾乎不太需要類別方法與類別屬性!
不是太複雜的程式, 可以直接以 .py 中的 全域變數與普通函數取代, 這個 .py 檔的中的類的 類屬性 與 類方法, 可以讓程式碼較簡潔清晰!


10. Python 物件導向介紹

類(class) 中的函數(function), 一般稱為 方法 method,
而由類為模板, 印出的具體的實作, 稱為 物件, 對象(object) 有時稱為實例(instance).

Ref:

    1. Cory Althoff, The self-taught programmer, Python 編程無師自通,
      gitHub上有原始碼, https://github.com/calthoff link

      tstp/part2, ch12 paradigm編程泛式之後段,
      tstp/part2, ch13 the_four_pillars_of_oop 物件導向之四大支柱,
      tstp/part2, ch14 more_object_oriented_programming 更多物件導向,
      以上三章之codes, 有物件導向的說明程式碼
    1. 21天學會Python
    1. 他的例子較為繁瑣, 故不建議閱讀他的書有關物件導向這方面的例子: 洪錦魁, Python 王者歸來, ch12 類, 清華大學出版, 2019.
    1. 對初學者, Python 物件導向, 寫得較深入又不致太繁瑣是以下這本:
      AI Sweigart, Beyond the basic stuff with Pyhton,
      中譯本: H&C譯, Python 功力提升的樂趣, 基峰出版, 2021.

1 與 2 這兩本書的講解, 較簡單易懂, 初學者可以很快了解, 但是較進階的概念, 可以再自行閱讀較完整的資料, 例如
6. Dusty Phillips, Python3 object oriented programming, Pyhton3 面對對象編程, 電子工業.

起手式: 定義一個類, class 類名稱 :

class 類名稱:
    變數之定義或方法之定義
    ,,,,,,,,
    ,,,,,,,

以下定義一個 橘子 class,
我們在 class 內定義一個方法 info(), 可以打印出一些基本訊息
注意 , info() 必須至少有一個引數 self, 也就是 , 用
def info( self):

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
class Orange:
    def info(self):
        print("Orange object created!")

產生一個 orange 物件的方法是執行 foo1 = Orange(),

>>> foo1 = Orange()

第二式: 點語法 .

要讓 foo1 這個 orange 物件呼叫 info(), 打印出訊息, 就要用點語法
foo1.info()

>>> foo1.info()
Orange object created!

第三式: 初始化之方法 init ( )

可以定義一個初始化之方法 __init__ ( ) , 讓 每次產生一個 orange 物件時, 就自動執行 打印出訊息 的動作.

定義一個初始化之方法 __init__ ( ), 每產生一個物件就會自動執行這個初始化方法 __init__ ( ) 的內容.
(注意: 是雙下畫線, _ _init_ _ ( ) 在鍵盤輸入時是雙下畫線, 不要有空格 )

def __init__(self):    
    方法的內容,,,,,
    ,,,,,

def init(self):
  本方法之內容
⋯ \cdots

以下把 print(“Orange object created!”) 放在這個__init__ ( )內

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
class Orange:
    def __init__(self):
        print("Orange object created!")

每當一產生一個 orange 物件, 就自動執行 打印出訊息 print(“Orange object created!”)

>>> orange = Orange()
Orange object created!

就不需要用點語法去取用 info(), 多一個動作.

第四式: 增加實例(物件)屬性(attribute) 的定義

屬性(attribute) 就是變數, 例如身高, 科目分數等, 在物件導向裡習慣稱為屬性.
可以在 __init__ ( ) 裡增加 重量屬性 weight 跟顏色屬性 color 的定義.
注意要用 self.weight, self.color 去定義或更改值:

self.weight = 6
self.color = 'orange'

像 self.weight, 用 self. 定義的屬性(變數) 是稱為物件屬性,
物件屬性不會繼承下去, 他是只有定義這個屬性的物件可以更改這個屬性的值,

(至於類屬性則是在類裡面沒有使用 self. 定義的屬性(變數), 可以當作所有物件之間的全域變數. 類屬性可以不需要, 可以用一個 .py 檔的全域變數代替也可以有同樣的效果 , Ref: AI Sweigart, Beyond the basic stuff with Pyhton,
中譯本: H&C譯, Python 功力提升的樂趣, 基峰出版, 2021, Ch16, P.352.
AI Sweigart 書中建議幾乎不太需要類別方法與類別屬性!)

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# 初始化函數增加定義 重量跟顏色的屬性(attribute)
# orange_attribute_3.py
class Orange:
    def __init__(self):
        print("Orange object created!")
        self.weight = 6
        self.color = 'orange'

orange = Orange()
print(orange.weight)
print(orange.color)
print(orange)
print(type(orange))

>>> 
= RESTART: C:\data\NEW\網路免費軟體資料\Python教學\Python書的札記\配套資源\Python編程無師自通_The Self-Taught Programmer_CoryAlthoff\资源\资源\tstp-master(Old one)\tstp-master\part_II\programming_paradigms\orange.py
Orange object created!
6
orange
<__main__.Orange object at 0x038D5D78>
<class '__main__.Orange'>


Ex1: 練習產生一個物件之語法, orangeEx1 = Orange(10, 'yellow') (此時就自動執行初始化動作了)

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# Ex1: 練習產生一個物件之語法, `orangeEx1 = Orange(10, 'yellow')` 
#(此時就自動執行初始化動作了)
class Orange:
    def __init__(self, weight, color):
        self.weight = weight
        self.color = color
        print("Orange object created!")

orangeEx1 = Orange(10, 'yellow')
print(orangeEx1.weight)
print(orangeEx1.color)

>>> 
= RESTART: C:/data/NEW/網路免費軟體資料/Python教學/Python書的札記/配套資源/Python編程無師自通_The Self-Taught Programmer_CoryAlthoff/资源/资源/tstp-master(Old one)/tstp-master/part_II/programming_paradigms/orange_ex1_20201028.py
Orange object created!
10
yellow

Ex4: 用點語法更改物件的變數(屬性 attributes)內容

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# Ex4 用點語法更改屬性
class Orange:
    def __init__(self, weight, color):
        self.weight = weight
        self.color = color
        print("Orange object created!")

an_orange = Orange(10, "dark orange")

an_orange.weight = 100
an_orange.color = "light orange"

print(an_orange.weight)
print(an_orange.color)


>>> 
= RESTART: C:\data\NEW\網路免費軟體資料\Python教學\Python書的札記\配套資源\Python編程無師自通_The Self-Taught Programmer_CoryAlthoff\资源\资源\tstp-master(Old one)\tstp-master\part_II\programming_paradigms\orange_ex4.py
Orange object created!
100
light orange

同一個類可以產生很多物件(實體)

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# orange_multiple_oranges_4.py
class Orange:
    def __init__(self, weight, color):
        self.weight = weight
        self.color = color
        print("Orange object created!")

orange1 = Orange(4, "light orange")
orange2 = Orange(8, "dark orange")
orange3 = Orange(14, "yellow")

第五式: 定義實例(物件)方法 (method 方法, 函數)

orange_rot.py
增加一個腐爛值 mold() 的計算方式的函數(方法)

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# orange_rot_5.py
class Orange():
    def __init__(self):
        """all weights are in oz"""
        self.weight = 6
        self.color = 'orange'
        self.mold = 0

    def rot(self, days, temperature):
        self.mold = days * (temperature * .1)

orange = Orange()
print(orange.mold)
orange.rot(10, 98)
print(orange.mold)

>>> 
= RESTART: C:\data\NEW\網路免費軟體資料\Python教學\Python書的札記\配套資源\Python編程無師自通_The Self-Taught Programmer_CoryAlthoff\资源\资源\tstp-master(Old one)\tstp-master\part_II\programming_paradigms\orange_rot.py
0
98.0

類中可以定義多個方法

rectangle.py
解釋類中可以定義多個方法

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
class Rectangle():
    def __init__(self, width, length):
        self.length = length
        self.width = width

    def calculate_area(self):
        return self.width * self.length

    def change_size(self, width, length):
        self.width = width
        self.length = length

rectangle = Rectangle(10, 20)
print(rectangle.calculate_area())
rectangle.change_size(20, 40)
print(rectangle.calculate_area())

>>> 
= RESTART: C:\data\NEW\網路免費軟體資料\Python教學\Python書的札記\配套資源\Python編程無師自通_The Self-Taught Programmer_CoryAlthoff\资源\资源\tstp-master(Old one)\tstp-master\part_II\programming_paradigms\rectangle.py
200
800

第六式: 類屬性 與 類方法

AI Sweigart 書中建議幾乎不太需要類別方法與類別屬性!
不是太複雜的程式, 可以直接以 .py 中的 全域變數與普通函數取代, 這個 .py 檔的中的類的 類屬性 與 類方法, 可以讓程式碼較簡潔清晰!

==類屬性=是在類裡面沒有使用 self. 定義的屬性(變數),
可以當作所有物件之間的全域變數 (可以用一個 .py 檔的全域變數代替也可以有同樣的效果).

類方法, 就是前面有用一個 @classmethod 修飾,
引數則有一個 cls,

例如:

# 類方法
    @classmethod
    def class_method(cls):
        print('class method called', cls)

Ref: Leechard, [Python]实例方法、类方法、静态方法 https://zhuanlan.zhihu.com/p/40162669 link.

  • 实例方法是一个普通的函数,类方法和静态方法都是通过函数装饰器的方式实现的;
  • 实例方法需要传入self,类方法需要传入cls参数,静态方法无需传入self参数或者是cls参数(但不等同于不能传入参数)

第六式: 繼承

我們先參考 Cory Althoff 的例子, 他的例子都很簡短, 看似簡單, 卻每次都挑定一個概念, 切中要點, 讓初學者可以很快掌握要點, 避免陷在複雜的程式碼中, 見樹不見林.

我們也會再寫較簡潔切中要點的數學方面例子, 會放在下一篇: 從turtle海龜動畫 學習 Python - 高中彈性課程系列 9.1 Python 物件導向的練習 link

原本部分參考洪錦魁的介紹, 但是他的例子極為繁瑣, 故不建議閱讀他的書有關物件導向這方面的例子.


上層類稱為 基類 base class
繼承的類稱為 衍生類 derived class

以下先定義一個長方形Rectangle 類, 再定義一個正方形Square類,
顯然, 正方形是長方形的特例, 所以可以用繼承的語法,
讓 正方形類可以直接使用長方形 類的屬性跟方法

底下 pass 是 Python 的關鍵字, 可以讓類或方法(函數)的定義, 內容先暫時不寫入明確之內容,

class Square(Rectangle):
    pass

因為用繼承的語法 class Square(Rectangle), 所以 Square 可以不需要定義自己的 __init__(),
而是直接使用 Rectangle 的 __init__(),

因為 正方形Square 的 寬width 跟 長length 是相等的,
假設我們要產生 長寬都是 20 的 Square 物件,
就如下, 輸入的引數是長寬都是 20:
a_square = Square(20,20)

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# inheritance_square_7.py

class Rectangle():
    def __init__(self, width, length):
        self.width = width
        self.length = length

    def print_size(self):
        print("{} by {}".format(self.width, self.length))


class Square(Rectangle):
    pass

a_square = Square(20,20)
a_square.print_size()

執行結果:

>>> 
= RESTART: D:\NEW_筆電的\網路免費軟體資料\Python教學\Python物件導向\Python編程無師自通_CoryAlthoff_物件導向在_tstp_part_II\part_II\the_four_pillars_of_oop\inheritance_square.py
20 by 20

第七式: 多型: 覆寫基類的方法

在衍生類中我們可以重新寫一個跟基類的同名的方法, 此時衍生類的同名的方法會被衍生類優先使用.

以下我們 改寫基類的 print_size() 方法,
初始化方法仍直接使用基類的
注意, 基類長方形計算面積函數, 是用長乘寬 width*length
而重新寫衍生類的正方形計算面積函數, 是用 邊長平方 width**2( width\* width)

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# inheritance_super_print_size_square_8.py

class Rectangle():
    def __init__(self, width, length):
        self.width = width
        self.length = length

    def print_size(self, width, length):
        print(f"{width} by {length}")


class Square(Rectangle):
   
    def print_size(self, width):
        print(f"{width} by {width}")
    

a_square = Square(20, 20)
width = a_square.width
a_square.print_size(width)

執行結果

>>> 
= RESTART: D:\NEW_筆電的\網路免費軟體資料\Python教學\Python物件導向\20230512_csdn_OOP_講義\inheritance_super_print_size_square_8.py
20 by 20

第八式: 多型: 用 super() 改寫基類的方法

在衍生類中我們想寫一個跟基類的同名的方法,且希望重複利用現成的基類的大部分內容, 只希望改寫小一小部分, 可以使用 super() 關鍵字來改寫, (如果是多重繼承, 可以直接用某個基類的名稱, 例如使用 海龜類: Turtle.__init__(self, shape=square, visible=False), 此時不要有小括號!)

以下我們 用 super() 改寫基類的 __init__() 方法

# Cory Althoff, The self-taught programmer, Python 編程無師自通.
# inheritance_super_init_square_9.py

class Rectangle():
    def __init__(self, width, length):
        self.width = width
        self.length = length
        print(f"{width} by {length}")

    def area(self, ):
        print("ares is {self.width*self.length}")


class Square(Rectangle):
    def __init__(self, width):
        super().__init__(width, width)

a_square = Square(20)

執行結果

>>> 
= RESTART: D:\NEW_筆電的\網路免費軟體資料\Python教學\Python物件導向\20230512_csdn_OOP_講義\inheritance_super_init_square_9.py
20 by 20

第九式: 封裝: 私有屬性與私有方法

原本部分內容參考洪錦魁的介紹, 但是他的例子極為繁瑣, 故不建議閱讀他的書有關物件導向這方面的例子,

我們會再寫較簡潔切中要點的數學方面例子

私有屬性與私有方法無法被直接訪問, 只要另外寫一個公開的方法去取用他們即可.

在屬性(變數)與方法(函數)前面 加兩個下畫線, 就成為 ‘私有屬性與私有方法’,
例如
__name
__weight
__salary()
等等,

要使用私有方法 __salary(),
必須先定義一個公有的方法 salaryPub(), 在這個方法裡呼叫 私有方法 __salary(),

取得基類的私有屬性

原本部分採用洪錦魁的介紹, 但是他的例子極為繁瑣, 故不建議閱讀他的書有關物件導向這方面的例子, 猜測他可能自己也不是物件導向方面的專家.

取得基類的私有屬性很簡單,
只要另外寫一個公開的方法,
用 關鍵字 return, 傳回想要取得的某些私有屬性, 就解決了.

11. 觀摩與解析 Python turtle module demo 中碎形有關的 codes, 的物件導向的設計

References

  1. Cory Althoff, The self-taught programmer, Python 編程無師自通,
    gitHub上有原始碼, https://github.comcalthoff link

    tstp/part2, ch12 paradigm編程泛式之後段,
    tstp/part2, ch13 the_four_pillars_of_oop 物件導向之四大支柱,
    tstp/part2, ch14 more_object_oriented_programming 更多物件導向,
    以上三章之codes, 有物件導向的說明程式碼

  2. 21天學會Python

  3. 洪錦魁的書物件導向這方面的例子較為繁瑣, 故不建議閱讀有關物件導向這方面的例子: 洪錦魁, Python 王者歸來, ch12 類, 清華大學出版, 2019.

  4. 對初學者, Python 物件導向, 寫得較深入又不致太繁瑣是以下這本:
    AI Sweigart, Beyond the basic stuff with Pyhton,
    中譯本: H&C譯, Python 功力提升的樂趣, 基峰出版, 2021.

  5. Leechard, [Python]实例方法、类方法、静态方法 https://zhuanlan.zhihu.com/p/40162669 link.

1 與 2 這兩本書的講解, 較簡單易懂, 初學者可以很快了解, 但是較進階的概念, 可以再自行閱讀較完整的資料, 例如
6. Dusty Phillips, Python3 object oriented programming, Pyhton3 面對對象編程, 電子工業.

附錄

小心類的繼承語法語產生物件的語法有點類似

在之後的例子基類 Shape 類程式碼後增加兩行,
新增一個子類 Triangle,
可以讓三角形繼承形狀這類,
類的繼承語法:
class Triangle(Shape):
只要在小括號內放入要繼承之基類名稱即可, 可以放入兩三個基類名稱, 同時繼承多個基類,
注意不要與產生物件之初始化的語法混在一起,
上面是在定義 class 的時候的程式碼時, 有類名稱接著小括號,

而在產生物件時, 則是在例如指令視窗當下執行程式碼時,
也會有類名稱接著小括號, 此時是初始化輸入的引數用的,

這兩種時候的程式碼都有類似的型態, 很容易混淆初學者!

例如
產生物件的語法:
fooTriangle = Triangle('My triangle')
則是產生一個 Tirangle 的類, 小括號內(‘‘My triangle’), 是指此物件的初始化名稱, 叫做 ‘My triangle’.(並不是指繼承某個類叫’‘My triangle’))

類屬性 與物件屬性

AI Sweigart 書中建議幾乎不太需要類別方法與類別屬性!

以下稍進階但並不是很需要
類屬性可以不需要, 可以用一個 .py 檔的全域變數代替也可以有同樣的效果
Ref: AI Sweigart, Beyond the basic stuff with Pyhton,
中譯本: H&C譯, Python 功力提升的樂趣, 基峰出版, 2021, Ch16, P.352.

像 self.weight, 用 self. 定義的屬性(變數) 是稱為物件屬性.

至於==類屬性=則是在類裡面沒有使用 self. 定義的屬性(變數), 可以當作所有物件之間的全域變數(可以用一個 .py 檔的全域變數代替也可以有同樣的效果).

# By Prof. P-J Lai MATH NKNU 20201026
# Object Oriented Programming
# 注意: 取用類屬性還是要用 self.類屬性

class GeometryShape():
    class_name = "Geometry shape"

    # def __int__(self, a, side):
    def __init__(self, a, side):
        self.area = a
        self.sideNumber = side

    def class_info(self):
        #print('類變量值:', class_name)
        # 取用類屬性還是要用 self.
        print('類變量值:', self.class_name)
        print('實例變量值:', self.area)
        
    # 修改實例屬性
    def changeInstName(self, area):
        self.area = area

    # 修改類屬性
    def changeClassName(self, name):
        GoemetryShape.class_name = name

triangle = GeometryShape(3,2)
triangle.class_info()


# 取用類屬性還是要用 self.類屬性
# 成功執行 20230514
##>>> 
##====== RESTART: D:\NEW_筆電的\網路免費軟體資料\Python教學\Python物件導向\ObjectOriented1.py =====
##類變量值: Geometry shape
##實例變量值: 3

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值