Python 板


LINE

因為一樣是變數的問題,所以我直接回這個標題。 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個例子讓我感到很困惑,一個會被改,一個不會被改, 想請問為什麼會有這樣子的差異呢? ※ 引述《sbrhsieh (sbr)》之銘言: : ※ 引述《millerlai (Scent of Love)》之銘言: : : 你的例子,我稍微改一下值。 : : class CA: : : V1 = 'V1' : : def __init__(self): : : self.V2 = 'V2' : 以上這個 statement 執行後會產生一個 class object(應該說是 type instance) : 這個 object bind 在 此 statement 所在 scope 中的名稱為 'CA'. : 所以 CA.V1 可以說是 CA 所指涉的物件的 instance field. : 這在 Java 中也是如此, static field 是 Class(derived) object 的 instance : field. : : 以下的程式碼,第一行建立了一個型別為CA的obj1 instance。 : : 經過將obj1.V1設為"V_V" 之後,你覺得最後的輸出結果會是如何? : : obj1 = CA(); : 這個 statement 產生一個 object(CA instance), 該 object 有一個 instance : field: 'V2'. : : print(obj1.V1); : : print(obj1.V2); : : obj1.V1 = "V_V"; : : print(CA.V1); : : #---------output--------- : : V1 : : V2 : : V1 : : #---------output--------- : : 在Java裡面,可透過 static 關鍵字來宣告一個 static field,但是在Python中 : : static或instance field宣告無法從syntax上來判斷。 : : 以上面的例子來說明,如果CA的V1欄位是一個static欄位,那麼最後一次print的結果 : : 是V1卻不是V_V,這在Java的觀念裡是說不通的。 : : Python是根據欄位的取用者來決定其欄位是static or instance。 : : 當程式透過 obj1 取用V1欄位時,此時V1為instance欄位。 : : 當程式透過 CA 取用V1欄位時,此時V1為static 欄位。 : : 而CA在建構元中所寫的V2,是實體欄位沒有錯。 : 我也同意 CA.V1 不完全等同於 Java/C++ 中的 static field(data member) 這樣的 : 看法. : 但是我認為某種程度上把 CA.V1 看成是一種 static field 也無不可. static field : 在觀念上是屬於 Class object(此 Class 是以 Java 界的說法), 也就是說 static : field 是保存(依附)在 Class object 本身(不是依附在該 Class 建構出來的 : instance 上. 在 Python 中也是如此, CA.V1 是依附在 CA 所指涉的 type instance : 中, 由 CA 所建構的多個 instance 共享. : Python 中的 object(a type name) 所實作的 __getattribute__ method, 除了會在 : 物件本身的 namespace 裡尋找外, 也會蒐尋物件所屬的 class object, 所以上例中 : 在尚未 assign 一個物件進 obj1 的 namespace 之前, obj1.V1 也可以存取到 CA.V1 : 所綁定的值. obj1.V1 = "V_V" 這個 statement 是把 "V_V" 這個 object bind 在 : obj1(指涉的物件)的 namespace(或說 __dict__), 而遮蔽了 CA.V1. : 以下這個 Java code 可以說跟文中前段的 Python code 有很高程度上的相似性. : public class CA { : public static String V1 = "V1"; : public String V2; : public String _V1; : public CA() { : this.V2 = "V2"; : } : public static void main(String[] args) { : CA obj1 = new CA(); : System.out.println(obj1.getV1()); : System.out.println(obj1.V2); : obj1.setV1("V_V"); : System.out.println(CA.V1); : } : public String getV1() { : return _V1 != null? _V1 : V1; : } : public void setV1(String value) { : this._V1 = value; : } : } : 基於 Java 中的 class member(field/method)在 class resolve 之後就固定, 所以 : 只能用依據一個 field 的值是否為空(null)來模擬 field 是否存在. --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 115.82.4.128







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燈, 水草

請輸入看板名稱,例如:Boy-Girl站內搜尋

TOP