Python 板


LINE

--前言 這文章標題不知道下的好不好 我也沒爬文 如果已有類似觀念 麻煩推文說一下 本來還想把python原文書賣掉 發生這件人為bug後 還是留起來吧XD --內容 這是個關於定義函式時 給定預設值 與 mutable object 的概念 為了簡化實際的案件 下面是一個例子 def show_append(x=[],y=2): x.append(y) print x 寫成這樣... 本來的意思是希望 show_append函式裡的二個變數 x 是個有 append method 的 object y是被 append 的值 如果都沒給值的話 就來個範例 空的list 與 被加入的數2 但很多事情總是不如想像... 下面來三個範例 >>> show_append() [2] >>> show_append() [2, 2] >>> show_append() [2, 2, 2] 這...這飯粒...有毒 跟預想的不一樣 原因是: 在定義函式中 預設的變數(x跟y) 是在定義函式執行時所產生(不是在呼叫的時候) 所以 x (也就是[])是在定義show_append函式時 就一直存在的東西 而因為[] 是mutable obj 在使用 append 這個in-place change的方法時 本身就會改變 所以 要範例的話 可以如下 >>> show_append([]) [2] 給個新的"[]" 就行了 順帶一提 >>> show_append() [2, 2, 2, 2, 2] 原來的預設值還在喲~ 順帶再提 也許你可能會這樣想 如果給x一個新的值[]行不行 像下面 >>> show_append(x=[]) [2] x的預設直就變成空的[]了~?? 當然是不行... 否則假使你用 show_append (y=3) 以後不就都append 3了?(又違反意思了) 在定義函式裡 使用的預設值 比方 def func(name = value_d): ... 呼叫func(name = value) 並不是創建name,並給一個新的值value 所以你不能在呼叫show_append時創建新的變數 像 show_append(another_value = 99) 呼叫時用的name 只是拿來對應func裡的name用而已 (找名字) 預設的value_d值仍然存在 所以 >>> show_append() [2, 2, 2, 2, 2, 2] 一個也沒少喲~ --結論 要注意給函式的預設值是否為mutable,是否符合創造函式的原意 記住python這樣的特性 運用在該用的地方吧!! 記得 力量越大 bug也越大... 共de之 --題外話 總覺得不會碰上的事 總是會碰上...orz 當這樣的問題發生在class裡頭的__init__時候 就更難發現了(我這是這種) 希望不要跟我犯一樣的錯...(還是只有我... 以上 歡迎指正與分享 --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.63.202
1F:→ DigiPrince:http://tinyurl.com/7r3w2y 11/15 17:31
2F:→ KSJ:看來是只有我了 囧... 11/15 17:45
3F:→ mathfeel:每次show_append()之后跑help(show_append)。有甚麼發現 11/15 18:10
4F:→ KSJ:在idle下 show_append( 之後就破梗了 x=會越來越長XD 11/15 18:18
5F:→ sbrhsieh:Python 中除了 global ...,其實是沒有 definition 的 11/15 20:41
6F:→ sbrhsieh:這個例子改寫成 C++,不也是一樣的行為嗎? 11/15 23:21
是指說 在runtime才"執行"產生函式嗎@@? 說來殘愧... 我在c與c++寫函式的時候還沒用過default值... 在我初學oop觀念時碰到的是python而非c++ c++的 private public的觀念 或是宣告class的方式 相較於python都較令我難理解 例如c++ . -> 在python下都是 . 理解能力的需求就不一樣 不過當然在c++的程式碼上 可讀性也許不夠 但理解後觀念會更清楚吧 我覺得還是該弄懂c++的類別觀念與寫法 (也許先略懂指標吧... 很多python相關的套件 說明文件還是在c++下較完整 例如PyQt 要了解而使用 以免像我對python def的誤用
7F:推 mikapauli:不要創造會改變外部物件的函式,就沒這個問題了w 11/16 01:19
8F:推 mikapauli:一般都會先做適當的copy說 11/16 01:22
其實我還蠻常用把cls instance當做變數在函式(別的class裡的)內傳來傳去 大部份是讀取需要的資料 修改資料的話就直接用method了 (classinstance.method("資料")) 我覺得在函式中修改instance時用instance的method 感覺還ok說 所以我覺得創造修改外部物件的函式應該是需要的 不知道這觀念對不對... 而我是以為class def __init__(self, arg = another_instance_create) 時 會重新創造 default arg裡的東西 所以中招了XD (如1F的文件的 important部份)
9F:→ sbrhsieh:哎呀,我搞錯了。寫成 C++ 在寫法上沒有等效... 11/16 12:23
10F:推 kdjf:到python3就很好理解了, 因為function也是class 11/17 09:43
我參考的原文書裡有提了許多 3與2不同的地方 print, string type, type & class, range 等等 不知道function的修改呢~ 有空再來看看:) (這讓我想到 剛學python就抓3下來因為print變成func而無法helloworld的一段往事) 不過我目前使用的相關套件在2下仍有比較好的支援度 所以3還可以再緩一下吧 (我目前是用python2.5較多)
11F:推 darkgerm:推~寫得好清楚~ 11/19 02:14
※ 編輯: KSJ 來自: 180.176.140.46 (11/19 16:28)
12F:推 mikapauli:真的需要的話當然OK阿,只是一般函式是沒有side effect的 11/20 21:09







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Tech_Job站內搜尋

TOP