python黑魔法之参数传递
我们都听说,python世界里面,万物皆对象。 > class A: pass > a = A() 我们说a是一个对象。 > a = 3 > b = a > b = 3 + 1 > print b 4 > print a 3 > a = [] > b = a > b.append(1) > print a [1] > print b [1] 不是都说python所有对象都是引用传递吗?为毛第一个b不是3? > a = (1,2,3) > a[0] = 10 TypeError: 'tuple' object does not support item assignment > a = {} > a[0] = 10 有了上面的两个例子,相信大家已经有了基本的认识。 > a = 3 > id(a) 140248135804168 > id(3) 140248135804168 > id(4) 140248135804144 > a = a + 1 > id(a) 140248135804144 you see ? 当我们执行a=a+1 后,id(a) 已经改变了。
第2步只是一个引用的改变。重点在第1步。a + 1,那么python实际上会调用a.__add__(1)。 > a = "hello" > id(a) 4365413232 > b = "hell" > id(b) 4365386208 > id(a[:-1]) 4365410928 > id(a[:-1]) 4365413760 看到了吗?虽然值相同,但是还是指向(创建)了不同的对象,尤其是最后两句,哪怕执行相同的操作,依然创建了不同的对象。 > a = "hello" > ret = set() > for i in range(1000): ret.add(id(a[:-1])) > print ret {4388133312,4388204640} 看到了吗?python还是挺聪明的。不过具体的缓存机制我没有深究过,期望有同学能分享下。 def fun(data): data = 3 a = 100 func(a) print a # 100 不是尼玛引用传递吗?为毛在执行func(a)后,a 的值没有改变呢?这里犯了一个动态语言基本的错误。 > def func(m): m[3] = 100 > a = {} > print a {} > func(a) > print a {3:100} 现在同学们知道该如何进行参数传递了吧?好嘞,进阶! def func(a=[]): a.append(3) return a 可能有同学会说了:我去!这么简单?来骗代码的吧? > print func() [3] > print func() [3,3] > print func() [3,3,3] 这真的是你想要的结果吗? def func(a=[]): print id(a) a.append(3) return a > print func() 4365426272 [3] > print func() 4365426272 [3,3] > print func() 4365426272 [3,3] 明白没?原来在python中,*默认参数不是每次执行时都创建的!* def func(a=None): if a is None: a = [] 这里在顺带提一下==,is: def func(*args): print id(args) > a = [1,2] > print id(a) 4364874816 > func(*a) 4364698832 > func(*a) 4364701496 看到了吧?实际上args也会产生一个新的对象。但是值是填入的传入参数。那么每一个item也会复制吗? def func(*args): print id(args[0]) > a = [1,2] > print id(a[0]) 140248135804216 > func(*a) 140248135804216 答案是,No。值会像普通list赋值一样,指向原先list(a)所引用的对象。 > a = [1,2] > b = (a,3) > b[1] = 100 TypeError: 'tuple' object does not support item assignment > print b ([1,2],3) > b[0][0] = 10 > print b ([10,3) 最最最后,我有个对象,它本身应该是 mutable 的,但是我想让他具备类似immutable的特性,可以吗? class A: def __setattr__(self,name,val): raise TypeError("immutable object could not set attr") 以上就是为大家介绍的python黑魔法,希望对大家的学习有所帮助。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |