老師你好,看到裝飾器,所以我又來了XD這一次有看到老師示範了summation的計算,因為我以前在物理系都是學這種類型的計算居多,我們以前學的是直接 def f(x): i = 0 for j in range(0,1+x): i = i+j return i print(f(50)) 這樣看起來功能好像沒有什麼不一樣而且程式碼看起來比較簡潔。所以我想跟老師確認的是,裝飾器是因為在程式裡面有時候會因為LOCAL跟GLOBAL的關係才需要用到裝飾器嗎?因為我對裝飾器很感興趣但我還沒有搞清楚裝飾器的用途在哪裡,謝謝老師。
講的真清楚!自己看原文看的頭暈腦漲,光聽老師您兩段視頻,就完全理解了。真是解惑呀!
謝謝你的回饋,很高興對你有幫助哦,讚!
看完裝飾器工廠對裝飾器的概念更加了解了。謝謝老師教學讓更多人可以學習
謝謝你的回饋,覺得很棒 :)
YA更新了 趕緊來搶頭香! 謝謝老師~
哈哈哈,恭喜頭香
老師寫的很好,謝謝老師無私分享
謝謝你的鼓勵,希望對大家有幫助 :)
看完傻眼,老師用30分鐘就搞定了我在其他網絡看了1個星期才懂的中階裝飾器😂,期待高階裝飾器教程《多重裝飾器地獄🥲》,慣例先like再看
哈哈哈,謝謝你的回饋哪 😂😂 好哦,你的期待是很好的建議 :)
聽比較資深的朋友講 多裝飾器其實不是很好耶
@@jakeyang3106 凡事過猶不及嘍 ~
@@cwpeng-course 真的 用最適當的方法去解決問題就好!
感謝老師的分享,終於學完這個章節了~
讚讚 :)
想請問老師最後的 show() 和 showEnglish() ()裡面如果放參數會跑到什麼地方呢?
感謝彭彭老師~ 還好有幫忙複習前面教的 裝飾器比較複雜沒複習會忘光光XD
======================================
# 裝飾器 Decorator - 基本篇
# 裝飾器 Decorator : 特殊設計的函示,用來 [ 輔助 ] 其他的函式
# 基本裝飾器
# 定義裝飾器
# def 裝飾器名稱(回呼函式名稱):
# def 內部函式名稱():
# 裝飾式內部的程式碼
# 回呼函式名稱()
# return 內部函式名稱
# 使用裝飾器
# @裝飾器名稱
# def 函式名稱():
# 函式內部的程式碼
# 函式名稱() # 呼叫帶有裝飾器的函式
# 程式範例
# def testDecorator(callback):
# def innerFunc():
# print("裝飾器")
# callback()
# return innerFunc
# @testDecorator
# def decoratedFunc():
# print("普通函式")
# decoratedFunc() # 大方向 : 先執行裝飾器內部的程式碼再執行本來的程式碼
# 程式範例
# def testDecorator(callback):
# def innerFunc():
# print("裝飾器")
# callback(3)
# return innerFunc
# @testDecorator
# def decoratedFunc(data):
# print("普通函式",data)
# decoratedFunc() # decoratedFunc()->testDecorator(callback)->執行裝飾器內部程式碼innerFunc()->callback等於decoratedFunc->執行decoratedFunc
#===================================================
# 定義裝飾器
def myDeco(cb):
def run():
print("裝飾器中的程式碼")
cb(3) # 這個回呼函式,其實就是被裝飾的普通函式
return run
# 使用裝飾器
@myDeco
def test(n):
print("普通函式的程式碼",n) # 整個看在一起 就是一個帶有裝飾器的函式
test()
print("==============================")
# 以上為裝飾器運作的基本原則 是規矩 沒有道理
# 定義一個裝飾器,計算 1+2+...+50 的總和
def calculate(callback):
def run():
# 裝飾器想要執行的程式碼
result=0
for n in range(51):
result=n+result # 也可以寫 result+=n
# 把計算結果透過參數傳到被裝飾的普通函式中
callback(result)
return run
# 使用裝飾器 # 進行函式分工切割 裝飾器內部負責計算 show 負責顯示
@calculate
def show(result):
print("計算結果是",result)
@calculate # 只要用很簡單的語法就可以重複利用上面裝飾器內的功能,去輔助不同的函式來運作 重複利用只要用 @裝飾器名稱 很簡潔
def showEnglish(result):
print("Result is", result)
show()
showEnglish()
這部份我影片中沒有提到。會對應到最內層的 run 函式的參數,例如:
... 忽略
def run(arg):
... 忽略
... 忽略
show(3)
3 就會傳進 arg 中。
@@cwpeng-course 謝謝老師解惑!
29:19
老師想請問 我如果依照這個時間的程式檔案,我想在show()裡頭放參數可以嗎?會傳到哪裡去?
另外我在網路上有查到參數放入內部函式的地方(也就是run()這裡面),也有看到參數放到裝飾器工廠(calculateFactory()的地方)想請問差在哪裡?
可以,如果你最後寫 show(5) 這個 5 就會傳遞到 run 函式的參數,就必須把 run 寫成 def run(x) 加上參數名稱。
就是運作方式不同而已,至於實際用途要看情境才能個案判斷哪個比較順手好用。有些喜歡在裝飾器的地方就建立彈性,有些是在呼叫時才提供彈性。
听过的最清楚的中文教学
谢谢你的回馈 :)
老師你好,看到裝飾器,所以我又來了XD這一次有看到老師示範了summation的計算,因為我以前在物理系都是學這種類型的計算居多,我們以前學的是直接
def f(x):
i = 0
for j in range(0,1+x):
i = i+j
return i
print(f(50))
這樣看起來功能好像沒有什麼不一樣而且程式碼看起來比較簡潔。所以我想跟老師確認的是,裝飾器是因為在程式裡面有時候會因為LOCAL跟GLOBAL的關係才需要用到裝飾器嗎?因為我對裝飾器很感興趣但我還沒有搞清楚裝飾器的用途在哪裡,謝謝老師。
確實沒有非得用裝飾器不可,他只是提供一個封裝的技巧和可能性,如果你覺得其他封裝方式更加的便利,那確實就不會想要使用裝飾器。雖然定義的語法確實是複雜,但使用的語法是簡單的,以模組或套件開發者的角度來看,只要使用是簡單的,就會越多人願意試試看。
概念上裝飾器是針對函式做輔助,實際上就是把某些動作包裝在裝飾器中執行,再緊接著執行被裝飾的函式。當我們覺得對函式做輔助這個概念和我們想做的應用相當對味的時候,就可以使用。例子不多,最明顯的例子是 Flask 這個框架使用裝飾器來做路由處理。
也可以說是燈罩跟燈泡的關係
你想要紅色光 但是燈泡不能動 所以你就把燈罩改成紅色 這樣就是紅色光了
也許會疑問說我換燈泡就好啊
但如果是在工作業務上
公司規定你不能改原本的代碼
這時候裝飾器就派上用場了
還有另一種 就是要添加額外功能
比如說 像是如果今天有數以千計的def
公司指派你說 他們需要每個def的名稱
當然你可以一個一個進去寫 然後回傳
但 加個裝飾器就可以輕鬆搞定了
@@jakeyang3106 感謝說明和分享 :)))
@@jakeyang3106 感謝分享
看了好多遍...好難說真的懂 裝飾器跟函式 的不同,
看下面回覆 好像又懂了一點XD
確實很複雜 XDDD 建議可以多寫點程式,並且小小修改去測試每個動作之間的關係 ~
彭彭老師您好,感謝您無私的教學
讓我對於裝飾器有更深的體會
不過有個問題想請教您
為何夾帶的引數要以裝飾器工廠的方式於編寫Syntan candy時傳入?
用這種方式不就變成於封裝函數時傳入所需的引數值而不是在主程式內?🤔
為何不將所需的參數一同打包於裝飾器內並於主程式呼叫功能時傳入就好?
def show_func_name(func):
def run(*args):
print(f"The function name : {func.__name__}")
return func(*args)
return run
@show_func_name
def my_sum(*args):
return sum(args)
print(my_sum(1, 3, 5, 7))
我覺得你分享的程式也很好,是另外一種可能性。在我個觀點來看,這些不同的語法技巧都是不同的工具,若都能達到目標,就沒有優劣之分。若要談哪一種寫法比較好,那就要先談非常具體的情境,有了具體的應用和情境之後,我們才開始談哪一種寫法更好。
彭彭老師您好,想請問您在一開始裝飾器計算過程中有說過callback或是cb中裡面的參數()會放入一個字串例如:result,那下面裝飾器也會跟著放result讓他跑程式碼。
但是您在最後一個示範中上面的工廠所使用的是total,但是裝飾器下面卻使用result 雖然還是跑出結果,我有點不瞭解這邊是怎麼運作 前面都90%聽得懂 我都會自己把影片暫停! 但是您突然放result跟我所想的不太一樣,希望您能解答一下😅😅
彭彭老師我自己理解了~~! 您的影片真的很讚 反覆看幾遍真的會了解 哈哈
覺得你很仔細的思考和提問很棒,有理解就好了 :)
想請問老師,從前面的留言有看到您說若在show()中新增參數會對應到def run()裡的參數,我做了嘗試後,發現如果改成以下code時,也能跑出我們想要的結果。
以"1加到某數(n)的總和"這個例子來看,感覺不使用到裝飾器工廠(DerFac)的方式,似乎更有彈性(因為DerFac若要把不同n以不同方式列印,show()跟showEng()好像也重新打很多次)
想問(終於要問了 XD),是這個例子剛好兩種方式都可以,還是通常會用到DerFac是在數據更龐大的情況下呢?
但如果裝飾器主要計算的是在內部程式內,不是只需要裝飾器也可以嗎...@@
def sum(cb):
def run(max):
Sum=0
for n in range(max+1):
Sum=Sum+n
cb(Sum)
return run
@sum
def show(n):
print("加總的總和",n)
@sum
def showEng(n):
print("Result is",n)
show(11) #印出 加總的總和 66
show(100) #印出 加總的總和 5050
showEng(11) #印出 Result is 66
showEng(100) #印出 Result is 5050
=======================================================================
廢話一堆之後,還是要謝謝老師!!!
每一部影片都很清楚的說明,我從4/18開始每天都在看這個入門課程,想不到竟然不到五天看完XD
以前曾經修過程式語言的課程,但當時上了一學期還是不知道自己在幹嘛,曾經一度害怕碰code
但這幾天上課時,過程實在是舒服愉快的,常常感覺時光飛逝
我要再繼續上老師後面的NumPy了 XDD
你問的這個是個相當深入的問題,我必須說表面上就如你所說,兩種方式都可以達成目的。
而比較深入的思考,就像是當你要把工作切割開來的時候,這個彈性要放在誰那邊?是要放在裝飾器工廠那邊,還是要放在函式呼叫這邊。有可能裝飾器工廠是由一個團隊開發的,而使用裝飾器的函式是由另一個團隊開發的,這樣子來看程式碼的分工,就會開始有一點遵循的方向了。
好人一生平安
謝謝 :)
謝謝老師
:)
请问怎么购买会员,找不到入口
可能 TH-cam 没有支援购买哦,不好意思 @@
這跟其他程式語言的巢狀函式差在哪?
python什麼時候才會支援多行的匿名函式
巢狀函式應該都差不多,但實務上不需要刻意去比較每個語言的差異 ( 除了回答別人問題以外 ),畢竟寫 Python 就是走 Python 的邏輯,寫 C 就走 C 的邏輯,完全分開思考是合理的。
我也不知道,可能要問問看那個開發 Python 引擎的團隊 XDDD
@@cwpeng-course 那我有得等了~連其他程式語言的switch case,python直到3.10版才用match實做出來
請問老師,使用裝飾器和def都可以節省code,那使用的時機是什麼? 謝謝
裝飾器可以讓執行函式前去做點什麼事情這種感覺,有些時候用函式來做看起來會比較醜一點。時機就是同樣的問題,可以用函式也可以用裝飾器來處理,哪一種寫法覺得比較乾淨俐落,就用哪一種。
請問無論是裝飾器還是裝飾器工廠 有辦法做出大量的裝飾嗎(抱歉我不知道專有名詞怎麼說) 我想表達的是 以老師的例子 我能不能做到像是中文輸出的結果是1+2+...+max 而英文輸出的結果我想做出1*2*...*max的結果 而我唯一需要做的就是在@後面做一點點的改變 像是更改裝飾器工廠的變數甚麼的??
盡可能地利用參數去作出彈性,你可以設計裝飾器工廠使用多個參數,其中一個參數決定要做的是加法還是乘法。
想問老師,大概看到老師影片到哪個階段可以開始刷題(python) ,沒寫題目有點不踏實
如果已經按照順序看到這部影片的話,其實就可以了。刷題需要的能力不是更多的程式語法,而是如何運用基本的語法去完成題目要求。
老师 一只看你视频,可以制作一些 关于股票 期货 外汇得量化编程教学嘛?期待中~
谢谢你的建议,我会尽量考虑看看的 :)
在内部程式里写参数,然后回传,好像也没有什么区别。?求指教。
程式经常有很多写法,例如也可以不用任何函式一样能完成工作。所以就只是考虑看看这样的写法是否让我们的程式看起来更舒服,更容易维护和开发而已。
老师,可以用支付宝不?成为会员
目前没办法哦,不好意思 @@
老師有打算教Ruby嗎
目前沒有哦 XD
老師,請問裝飾器工廠和以下的函式有何差别🤔🤔
def plus3(n):
return n*3
def test1():
print(plus3(3))
test1()
很喜歡老師的影片,真的很謝謝老師😊😊
你可以當成裝飾器工廠是某種程式碼的設計模式,執行的結果確實可以是一樣的,但有些時候我們會覺得使用裝飾器的程式更容易維護和理解。
裝飾品真的可以很複雜
同意 XD
我尝试在装饰器 @testde01 上调用 add(7),但是由于 @testde01 装饰器将 add 函数替换为 run 函数,因此实际上在调用的是 run 函数,而不是 add 函数。
def testde01(add):
def run(kwargs):
print("provide numbers")
you=add(4)+kwargs
print(you)
return run
@testde01
def add(arg):
global sumtest
for i in range(arg):
sumtest+=i
print("i",i)
return sumtest
add(10)
#def decorator factory()
#def decorator name
sumtest = 0
def myfactory(base):
def mydecorator(callback):
def run(kwrags):
print("The kwargs :",kwrags)
u=callback(base)+kwrags
print(u)
return run
return mydecorator
@myfactory(6)
def add(arg):
global sumtest
for i in range(arg):
sumtest+=i
print("i",i)
return sumtest
add(30)