“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:
-
- 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, 有物件導向的說明程式碼
- Cory Althoff, The self-taught programmer, Python 編程無師自通,
-
- 21天學會Python
-
- 他的例子較為繁瑣, 故不建議閱讀他的書有關物件導向這方面的例子: 洪錦魁, Python 王者歸來, ch12 類, 清華大學出版, 2019.
-
- 對初學者, Python 物件導向, 寫得較深入又不致太繁瑣是以下這本:
AI Sweigart, Beyond the basic stuff with Pyhton,
中譯本: H&C譯, Python 功力提升的樂趣, 基峰出版, 2021.
- 對初學者, Python 物件導向, 寫得較深入又不致太繁瑣是以下這本:
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
-
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, 有物件導向的說明程式碼 -
21天學會Python
-
洪錦魁的書物件導向這方面的例子較為繁瑣, 故不建議閱讀有關物件導向這方面的例子: 洪錦魁, Python 王者歸來, ch12 類, 清華大學出版, 2019.
-
對初學者, Python 物件導向, 寫得較深入又不致太繁瑣是以下這本:
AI Sweigart, Beyond the basic stuff with Pyhton,
中譯本: H&C譯, Python 功力提升的樂趣, 基峰出版, 2021. -
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