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

请输入看板名称,例如:Soft_Job站内搜寻

TOP