一直对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而言,对应的*和**则相当于进行了浅层复制的传递