python函数传递list,tuple和dict时的复制关系

来源:互联网 发布:淘宝开店名字 编辑:程序博客网 时间:2024/05/19 12:38

一直对python函数中的参数关系理不清,今天就来动手解决之!

一、首先看看list的参数:

  1 #!/usr/bin/env python
  2 
  3 def foo(ls):
  4     print id(ls)
  5     ls[0]=ls[1]+ls[2]
  6 
  7 def main():
  8     lst = [1991,12,04]
  9     foo(lst)
 10     print id(lst)
 11     print lst
 12 
 13 if __name__ == '__main__':
 14     main()

这个小代码结果显示:

140023038189864
140023038189864
[16, 12, 4]

可见函数传递过去的是指向lst的指针


二、对于tuple:

  1 #!/usr/bin/env python
  2 
  3 #def foo(tp):
  4 def foo(*tp):
  5 #   tp[2][0]=tp[2][1]+tp[2][2]
  6     print id(tp)
  7     print tp
  8 
  9 def main():
 10     tp = ('a','s',[1991,12,04])
 11     foo(tp)
 12     print id(tp)
 13     print tp
 14 
 15 if __name__ == '__main__':
 16     main()

140151903512976
(('a', 's', [1991, 12, 4]),)
140151903439760
('a', 's', [1991, 12, 4])

可见函数体的*把传递过来的参数包装为一个tuple,把代码改为:

  1 #!/usr/bin/env python
  2 
  3 #def foo(tp):
  4 def foo(*tp):
  5     tp[2][0]=tp[2][1]+tp[2][2]
  6     print id(tp)
  7     print tp
  8 
  9 def main():
 10     tp = ('a','s',[1991,12,04])
 11     foo(*tp)
 12     print id(tp)
 13     print tp
 14 
 15 if __name__ == '__main__':
 16     main()
结果显示:

140699484027472
('a', 's', [16, 12, 4])
140699484027792
('a', 's', [16, 12, 4])         

函数调用的*把本来是容器的对象分解为单个的元素,在有函数体的*吧他们组合起来,

可以发现,得到的新tp不再是原来的了。           

再次修改代码为:  

  1 #!/usr/bin/env python
  2 
  3 #def foo(tp):
  4 def foo(*tp):
  5     tp[2][0]=tp[2][1]+tp[2][2]
  6     print id(tp[0])
  7     print id(tp[1])
  8     print id(tp[2])
  9     print tp
 10 
 11 def main():
 12     tp = ('a','s',[1991,12,04])
 13     foo(*tp)
 14     print id(tp[0])
 15     print id(tp[1])
 16     print id(tp[2])
 17     print tp
 18 
 19 if __name__ == '__main__':
 20     main()                                                                   

结果显示:

140720297669896
140720297669776
140720296530216
('a', 's', [16, 12, 4])
140720297669896
140720297669776
140720296530216
('a', 's', [16, 12, 4])

可见各个元素id都一样。再次修改:

1 #!/usr/bin/env python
  2 
  3 #def foo(tp):
  4 def foo(*tp):
  5     tp[2][0]=tp[2][1]+tp[2][2]
  6     print id(tp[2][0])
  7     print id(tp[2][1])
  8     print id(tp[2][2])
  9     print tp
 10     
 11 def main():
 12     tp = ('a','s',[1991,12,04])
 13     foo(*tp)
 14     print id(tp[2][0])
 15     print id(tp[2][1])
 16     print id(tp[2][2])
 17     print tp
 18     
 19 if __name__ == '__main__':
 20     main()

40075248
40075344
40075536
('a', 's', [16, 12, 4])
40075248
40075344
40075536
('a', 's', [16, 12, 4])

由此可知,这样传递相当于做了浅层复制。

三、同样,dict:

  1 #!/usr/bin/env python
  2 
  3 def foo(**dc):
  4 #   print id(dc)
  5 #   pass
  6     dc['a'] = 24
  7     print dc
  8     print id(dc)
  9     print id(dc['(1,2)'])
 10 
 11 
 12 def main():
 13     dct = {'a':12,'s':600,'(1,2)':668}
 14 #   print dct[(1,2)]
 15     foo(**dct)
 16     print dct
 17     print id(dct)
 18     print id(dct['(1,2)'])
 19 #   print id(dct)
 20 
 21 if __name__=='__main__':
 22     main()

结果显示:

{'a': 24, '(1,2)': 668, 's': 600}
140698470995400
26000456
{'a': 12, '(1,2)': 668, 's': 600}
140698470959656
26000456

可见和tuple一样是浅层复制。

四、综上:

在函数的参数传递过程中,如果是直接的值传递,相当于把对象的引用(指针)传递过去,对于tuple和dict而言,对应的*和**则相当于进行了浅层复制的传递

0 0
原创粉丝点击