SlideShare a Scribd company logo
1 of 9
Download to read offline
附錄B 裝飾器
附 錄 B
裝 飾 器
python 程式設計
python 簡要講義
國立中央大學數學系 吳維漢
附錄B 裝飾器
python 函式為第一類物件 (一)
2
 python 函式為第一類物件(first-class object)
 函式可當成物件使用
 函式可當成參數傳入另一個函式使用
def square( fn , a , b ) :
return [ fn(x) for x in range(a,b+1) ]
# 將 abs 傳入 square 函式使用
print( square( abs , -2 , 2 ) ) # 印出 [2, 1, 0, 1, 2]
def square( a , b ) :
return [ x*x for x in range(a,b+1) ]
# foo 即是 square
foo = square
print( foo( -2 , 2 ) ) # 印出 [4, 1, 0, 1, 4]
附錄B 裝飾器
python 函式為第一類物件 (二)
3
 函式可回傳函式
 函式內可定義函式
# 回傳設定係數後的一元二次方程式函式
def spoly( a , b , c ) :
return lambda x : a*x*x + b*x + c
# fn = x**2 + 2*x + 1
fn = spoly(1,2,1)
for x in range(3) :
print( x , fn(x) ) # 印出:0 1,1 4,2 9 共三列
def fsum( f , g ) :
# fn 為兩函式之和
def fn(x) : return f(x) + g(x)
return fn
def square(x) : return x * x
def cubic(x) : return x * x * x
# h(x) = square(x) + cubic(x)
h = fsum( square , cubic )
for x in range(0,3) :
print( x , h(x) ) # 印出:0 0,1 2,2 12 共三列
附錄B 裝飾器
python 函式為第一類物件 (三)
4
 函式可存入其它資料型別中
# 使用上例的函式
fns = [ square , cubic ] # fns 串列內存兩函式
for x in range(0,3) :
print( x , end=" " )
for fn in fns :
print( fn(x) , end=“ ” ) # 印出:0 0 0,1 1 1,2 4 8 三列
print()
附錄B 裝飾器
函式裝飾器 (一)
5
 函式裝飾器:以函式當為裝飾器
 用來包裝函式的函式,擴充原有函式功能
1. 版本一
def square(x) : return x*x
def cubic(x) : return x*x*x
# 計算在 x 在 [a,b] 之間的函數數值和
def fsum_over( fn , a , b ) :
return sum( [ fn(x) for x in range(a,b+1) ] )
# 分別將 square 與 cubic 函式當成參數傳入
print( fsum_over( square , -2 , 2 ) ) # 印出:10
print( fsum_over( cubic , -2 , 2 ) ) # 印出:0
 以上 square、cubic、fsum_over 三函式各自獨立
附錄B 裝飾器
函式裝飾器 (二)
6
2. 版本二
def square(x) : return x*x
def cubic(x) : return x*x*x
# decorate 函式名稱,非保留字
def decorate( fn ) :
def fsum_over( a , b ) :
return sum( [ fn(x) for x in range(a,b+1) ] )
return fsum_over
# decorate 回傳的 fsum_over 被當成新的 square,square 函式不再是
原有 square
square = decorate(square)
# 這裡的 square 事實上是 fsum_over 函式,square 變成雙參數函式
print( square(-2,2) ) # 印出:10
 以上接收的 square 函式是原有函式 square 與 fsum_over 的合體函式,等同
square 函式經過 decorate 裝飾器函式的處理後「融合」了兩個函式功能,造成
square 函式產生質變,由單參數函式變為雙參數函式。
附錄B 裝飾器
函式裝飾器 (三)
7
def rangesum( fn ) :
def fsum_over( a , b ) :
return sum( [ fn(x) for x in range(a,b+1) ] )
return fsum_over
def square(x) : return x*x
square = rangesum(square)
def cubic(x) : return x*x*x
cubic = rangesum(cubic)
可分別簡化為:
def rangesum( fn ) :
def fsum_over( a , b ) :
return sum( [ fn(x) for x in range(a,b+1) ] )
return fsum_over
@rangesum
def square(x) : return x*x
@rangesum
def cubic(x) : return x*x*x
 裝飾器簡化語法:
附錄B 裝飾器
類別裝飾器 (一)
8
 類別裝飾器:以類別當為裝飾器
 函式運算子:__call__
class RangeSum :
def __init__( self , fn ) :
self.fn = fn
# 函式運算子:讓物件可用函式方式執行實例方法
def __call__( self , a , b ) :
return sum( [ self.fn(x) for x in range(a,b+1) ] )
# 輸入 abs 絕對值函式
foo = RangeSum( abs )
# 以下兩者相同,都印出 12
print( foo.__call__(-3,3) )
print( foo(-3,3) )
 foo 為 RangeSum 物件,foo(-3,3) 等同 foo.__call__(-3,3)
附錄B 裝飾器
類別裝飾器 (二)
9
 使用類別裝飾器:需定義類別的函式運算子
@RangeSum
def square( x ) : return x*x
@RangeSum
def cubic( x ) : return x*x*x
# 分別執行 RangeSum 的函式運算子
print( square(-2,2) ) # 印出:10
print( cubic(-2,2) ) # 印出:0
 定義類別裝飾器時需連同設定類別的函式運算子

More Related Content

What's hot (20)

Ch10 範例
Ch10 範例Ch10 範例
Ch10 範例
 
Ch10 教學
Ch10 教學Ch10 教學
Ch10 教學
 
Ppt 127-135
Ppt 127-135Ppt 127-135
Ppt 127-135
 
Ch11 教學
Ch11 教學Ch11 教學
Ch11 教學
 
Ppt 1-50
Ppt 1-50Ppt 1-50
Ppt 1-50
 
Ch8 教學
Ch8 教學Ch8 教學
Ch8 教學
 
Ppt 78-100
Ppt 78-100Ppt 78-100
Ppt 78-100
 
Ppt 51-77
Ppt 51-77Ppt 51-77
Ppt 51-77
 
Python p.193 197
Python p.193 197Python p.193 197
Python p.193 197
 
Sym py edu
Sym py eduSym py edu
Sym py edu
 
Ch12 範例
Ch12 範例Ch12 範例
Ch12 範例
 
Ppt 1-25
Ppt 1-25Ppt 1-25
Ppt 1-25
 
Ch7 教學
Ch7 教學Ch7 教學
Ch7 教學
 
Ch12 教學
Ch12 教學Ch12 教學
Ch12 教學
 
Ch4 教學
Ch4 教學Ch4 教學
Ch4 教學
 
Ch5 教學
Ch5 教學Ch5 教學
Ch5 教學
 
P127 135 new
P127 135 newP127 135 new
P127 135 new
 
Ch9 範例
Ch9 範例Ch9 範例
Ch9 範例
 
Ch6 教學
Ch6 教學Ch6 教學
Ch6 教學
 
Ch1 教學
Ch1 教學Ch1 教學
Ch1 教學
 

Similar to Appendix B 教學

Similar to Appendix B 教學 (20)

Appendix B
Appendix BAppendix B
Appendix B
 
ncuma_函數微分計算.pptx
ncuma_函數微分計算.pptxncuma_函數微分計算.pptx
ncuma_函數微分計算.pptx
 
函數微分_範例.pptx
函數微分_範例.pptx函數微分_範例.pptx
函數微分_範例.pptx
 
ncuma_函式.pptx
ncuma_函式.pptxncuma_函式.pptx
ncuma_函式.pptx
 
ncuma_函數畫圖.pptx
ncuma_函數畫圖.pptxncuma_函數畫圖.pptx
ncuma_函數畫圖.pptx
 
函數畫圖.pptx
函數畫圖.pptx函數畫圖.pptx
函數畫圖.pptx
 
Ch9
Ch9Ch9
Ch9
 
Ch5
Ch5Ch5
Ch5
 
Ch5
Ch5Ch5
Ch5
 
Ch8
Ch8Ch8
Ch8
 
Ch11 範例
Ch11 範例Ch11 範例
Ch11 範例
 
ncuma_SymPy符號運算套件.pptx
ncuma_SymPy符號運算套件.pptxncuma_SymPy符號運算套件.pptx
ncuma_SymPy符號運算套件.pptx
 
Ptyhon 教學 003 函數
Ptyhon 教學 003 函數Ptyhon 教學 003 函數
Ptyhon 教學 003 函數
 
SymPy在微積分上的應用:範例.pptx
SymPy在微積分上的應用:範例.pptxSymPy在微積分上的應用:範例.pptx
SymPy在微積分上的應用:範例.pptx
 
Ch 8
Ch 8Ch 8
Ch 8
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
 
Ch12
Ch12Ch12
Ch12
 
ncuma_Taylor 多項式.pptx
ncuma_Taylor 多項式.pptxncuma_Taylor 多項式.pptx
ncuma_Taylor 多項式.pptx
 
Ch10
Ch10Ch10
Ch10
 

More from hungchiayang1 (20)

Exercise 1 3
Exercise 1 3Exercise 1 3
Exercise 1 3
 
Python differential equation
Python differential equationPython differential equation
Python differential equation
 
化學系 python 習題
化學系 python 習題化學系 python 習題
化學系 python 習題
 
化學系 python 練習
化學系 python 練習化學系 python 練習
化學系 python 練習
 
化學系 python 教學
化學系 python 教學化學系 python 教學
化學系 python 教學
 
Ppt 151-151
Ppt 151-151Ppt 151-151
Ppt 151-151
 
Ppt 136-136
Ppt 136-136Ppt 136-136
Ppt 136-136
 
Ppt 143-143
Ppt 143-143Ppt 143-143
Ppt 143-143
 
Ppt 137-137
Ppt 137-137Ppt 137-137
Ppt 137-137
 
Ppt 150-150
Ppt 150-150Ppt 150-150
Ppt 150-150
 
Ppt 26-50
Ppt 26-50Ppt 26-50
Ppt 26-50
 
Ppt 145-149
Ppt 145-149Ppt 145-149
Ppt 145-149
 
Ppt 174-174
Ppt 174-174Ppt 174-174
Ppt 174-174
 
Ppt 144-144
Ppt 144-144Ppt 144-144
Ppt 144-144
 
Ppt 167-173
Ppt 167-173Ppt 167-173
Ppt 167-173
 
Ppt 152-155
Ppt 152-155Ppt 152-155
Ppt 152-155
 
Ppt 156-156
Ppt 156-156Ppt 156-156
Ppt 156-156
 
Ppt 166-166
Ppt 166-166Ppt 166-166
Ppt 166-166
 
Ppt 165-165
Ppt 165-165Ppt 165-165
Ppt 165-165
 
Ppt 157-157
Ppt 157-157Ppt 157-157
Ppt 157-157
 

Appendix B 教學

  • 1. 附錄B 裝飾器 附 錄 B 裝 飾 器 python 程式設計 python 簡要講義 國立中央大學數學系 吳維漢
  • 2. 附錄B 裝飾器 python 函式為第一類物件 (一) 2  python 函式為第一類物件(first-class object)  函式可當成物件使用  函式可當成參數傳入另一個函式使用 def square( fn , a , b ) : return [ fn(x) for x in range(a,b+1) ] # 將 abs 傳入 square 函式使用 print( square( abs , -2 , 2 ) ) # 印出 [2, 1, 0, 1, 2] def square( a , b ) : return [ x*x for x in range(a,b+1) ] # foo 即是 square foo = square print( foo( -2 , 2 ) ) # 印出 [4, 1, 0, 1, 4]
  • 3. 附錄B 裝飾器 python 函式為第一類物件 (二) 3  函式可回傳函式  函式內可定義函式 # 回傳設定係數後的一元二次方程式函式 def spoly( a , b , c ) : return lambda x : a*x*x + b*x + c # fn = x**2 + 2*x + 1 fn = spoly(1,2,1) for x in range(3) : print( x , fn(x) ) # 印出:0 1,1 4,2 9 共三列 def fsum( f , g ) : # fn 為兩函式之和 def fn(x) : return f(x) + g(x) return fn def square(x) : return x * x def cubic(x) : return x * x * x # h(x) = square(x) + cubic(x) h = fsum( square , cubic ) for x in range(0,3) : print( x , h(x) ) # 印出:0 0,1 2,2 12 共三列
  • 4. 附錄B 裝飾器 python 函式為第一類物件 (三) 4  函式可存入其它資料型別中 # 使用上例的函式 fns = [ square , cubic ] # fns 串列內存兩函式 for x in range(0,3) : print( x , end=" " ) for fn in fns : print( fn(x) , end=“ ” ) # 印出:0 0 0,1 1 1,2 4 8 三列 print()
  • 5. 附錄B 裝飾器 函式裝飾器 (一) 5  函式裝飾器:以函式當為裝飾器  用來包裝函式的函式,擴充原有函式功能 1. 版本一 def square(x) : return x*x def cubic(x) : return x*x*x # 計算在 x 在 [a,b] 之間的函數數值和 def fsum_over( fn , a , b ) : return sum( [ fn(x) for x in range(a,b+1) ] ) # 分別將 square 與 cubic 函式當成參數傳入 print( fsum_over( square , -2 , 2 ) ) # 印出:10 print( fsum_over( cubic , -2 , 2 ) ) # 印出:0  以上 square、cubic、fsum_over 三函式各自獨立
  • 6. 附錄B 裝飾器 函式裝飾器 (二) 6 2. 版本二 def square(x) : return x*x def cubic(x) : return x*x*x # decorate 函式名稱,非保留字 def decorate( fn ) : def fsum_over( a , b ) : return sum( [ fn(x) for x in range(a,b+1) ] ) return fsum_over # decorate 回傳的 fsum_over 被當成新的 square,square 函式不再是 原有 square square = decorate(square) # 這裡的 square 事實上是 fsum_over 函式,square 變成雙參數函式 print( square(-2,2) ) # 印出:10  以上接收的 square 函式是原有函式 square 與 fsum_over 的合體函式,等同 square 函式經過 decorate 裝飾器函式的處理後「融合」了兩個函式功能,造成 square 函式產生質變,由單參數函式變為雙參數函式。
  • 7. 附錄B 裝飾器 函式裝飾器 (三) 7 def rangesum( fn ) : def fsum_over( a , b ) : return sum( [ fn(x) for x in range(a,b+1) ] ) return fsum_over def square(x) : return x*x square = rangesum(square) def cubic(x) : return x*x*x cubic = rangesum(cubic) 可分別簡化為: def rangesum( fn ) : def fsum_over( a , b ) : return sum( [ fn(x) for x in range(a,b+1) ] ) return fsum_over @rangesum def square(x) : return x*x @rangesum def cubic(x) : return x*x*x  裝飾器簡化語法:
  • 8. 附錄B 裝飾器 類別裝飾器 (一) 8  類別裝飾器:以類別當為裝飾器  函式運算子:__call__ class RangeSum : def __init__( self , fn ) : self.fn = fn # 函式運算子:讓物件可用函式方式執行實例方法 def __call__( self , a , b ) : return sum( [ self.fn(x) for x in range(a,b+1) ] ) # 輸入 abs 絕對值函式 foo = RangeSum( abs ) # 以下兩者相同,都印出 12 print( foo.__call__(-3,3) ) print( foo(-3,3) )  foo 為 RangeSum 物件,foo(-3,3) 等同 foo.__call__(-3,3)
  • 9. 附錄B 裝飾器 類別裝飾器 (二) 9  使用類別裝飾器:需定義類別的函式運算子 @RangeSum def square( x ) : return x*x @RangeSum def cubic( x ) : return x*x*x # 分別執行 RangeSum 的函式運算子 print( square(-2,2) ) # 印出:10 print( cubic(-2,2) ) # 印出:0  定義類別裝飾器時需連同設定類別的函式運算子