Python 板


LINE

※ 引述《gardenest (股海尋燈)》之銘言: : 因為一樣是變數的問題,所以我直接回這個標題。 : 1、 : a = 1 : class testing: : def test(self): : a = 0 : print a : def test2(self): : print a : obj = testing() : obj.test() : obj.test2() : print a : ----------output : 0 : 1 : 1 : ----------- : 看起來像是最上面第一行a的值並沒有被test()改成0,所以後面印出來的還是1。 : 2、 : 但是當我將a改成list的型態時,它似乎會被改變了。 : a = [1] : class testing: : def test(self): : a.append(2) : print a : def test2(self): : print a : obj = testing() : obj.test() : obj.test2() : print a : ---------output : [1,2] : [1,2] : [1,2] : --------- : 看起來a在test()裡被改變了。 : 以上這2個例子讓我感到很困惑,一個會被改,一個不會被改, : 想請問為什麼會有這樣子的差異呢? 以下是我目前的理解,如果有什麼錯的地方還請各位指正^^ 先簡化一下問題 def function1(): a=1 print a return def function2(): print a return a=0 function1() function2() print a 結果是 1 0 0 因為python沒有變數宣告 所以當你在函式內assign一個值給某個變數時 它就當作在這個函式內產生一個區域變數 所以function1的a就被當成是區域變數,後面的print就是print區域變數的值 而function2內沒有名為a的區域變數,所以它就會去外面找最近的a來print 同樣的 def function1(): a=[1] print a return def function2(): print a return a=[0] function1() function2() print a 這樣會得到 [1] [0] [0] 還有一個有趣的行為是 def function1(): print a a=1 print a return a=0 function1() 它會回應: UnboundLocalError: local variable 'a' referenced before assignment 即是說,只要函式中任何一個位置assign了a的值,a就會在整個函式中被當成 區域變數(不管是assign前還是assign後),所以你就不能在assign之前對a取值 但是如果妳在函數中調用變數的method的話,因為函式中沒有同名的區域變數 所以它就會去外面找最近的同名變數 比如說 def function1(): a[0]=1 print a return a=[0] function1() print a 就會得到 [1] [1] 因為在function1中 讀到a[0]=1這一行時,它會去找function1中有沒有指定'a'為區域 變數,沒有的話就會去外面找最近的a來用囉 這個特性有時可以玩一些tricks 例如: counter=0 def function(): counter=counter+1 return counter function() 它會說 UnboundLocalError: local variable 'counter' referenced before assignment 因為沒有變數宣告的機制,所以它把counter當作是區域變數了 一個變通的方法就是使用global statement counter=0 def function(): global counter counter=counter+1 return counter function() function() function() 就會得到 1 2 3 ... 在這邊global counter這一行的意思就是告訴interpreter說在這邊的'counter' 要用的是"最外面"的counter 然而你也可以用前面所說的特性來達到同樣的效果,例如: counter=[0] def function(): counter[0]=counter[0]+1 return counter[0] function() function() function() 此外,global的使用還是有一些限制 例如: def geniter(): c=0 def iter(): global c c=c+1 return c return iter iter=geniter() iter() 它又會跟你說: NameError: global name 'c' is not defined 因為你使用global statement的時候 它會去「最外層」找全域變數來用 所以又會跟你說找不到… 但是使用前面的技巧,就還是可以達成目的: def geniter(): c=[0] def iter(): c[0]=c[0]+1 return c[0] return iter iter1=geniter() iter2=geniter() iter1() iter1() iter1() iter2() iter2() iter2() 就會得到 1 2 3 1 2 3 一個新聞是在python 3.0中多了 nonlocal statement可以用來表示 我要使用「上一層」的變數 所以應該就可以寫成 def generator(): c=0 def f(): nonlocal c c=c+1 return c return f 感覺上會變得比較直覺(沒有裝3.0所以沒試過) 總之沒有宣告變數的機制其實還是有一些不方便的地方啦 --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.213.158 ※ 編輯: mantour 來自: 140.112.213.158 (01/22 13:31) ※ 編輯: mantour 來自: 140.112.213.158 (01/22 13:33)
1F:推 aquarianboy:補充一下,第一個範例的結果應該是1 0 0 印了三次 :) 01/22 13:59
謝謝 已改^^ ※ 編輯: mantour 來自: 140.112.213.158 (01/22 14:01)
2F:推 gardenest:感謝man大的解答,非常詳細,這個問題困惑我好久,終於 01/22 15:38
3F:→ gardenest:決了^__^ 01/22 15:38
4F:→ gardenest:解決了^__^ 01/22 15:39







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