传递参数
不可变对象“通过值”作为实参,像整数和字符串你不可在原处进行修改,所以就类似C中的机制,拷贝出来,更改的话,不会更改原处,而现在是相对它更改的话,会出错。
可变对象通过“指针”作为实参,列表和字典这样的对象可以通过对象引用进行传递。
实参的传递跟C语言还是有点区别,在python中它实际上都是把函数中的形参名指向一个对象,但是当形参A指向的是一个整数或字符串形式对象时,如果你在函数内对它重新赋值的话,它会指向一个新的对象。而如果形参A接受的实参是列表,字典等可变对象的话,这时分两种情况,如果你给它重新赋值的话,A就指向一个新的对象;如果你对A进行更改操作的话,它会影响到调用者。
>>> (L,M,N)=(3,[1,2],[5,6])
>>> def change(a,b,c):
... a=2 # a重新指向新的对象
... b='string' # b重新指向新的对象,所以传给它的M维持原样
... c[0]=7 # 对c接受的对象进行修改,所以实参C最后是更改后的形式
... print(a,b,c)
...
>>> change(L,M,N)
(2, 'string', [7, 6])
>>> (L,M,N)
(3, [1, 2], [7, 6])
为了防止改变会影响调用者,我们可以处理可变实参的拷贝,
change(L,M[:]) #方法一,因为M[:]会返回一个列表的拷贝
def change(a,b,c): #方法二,在函数中把实参的拷贝重新赋值给另一个变量,注意别写成b=b,这个时候b仍旧指向那个对象
b = b[:]
应用举例
下面的例子,需要你能够把握好for是进行迭代,后面可以接可迭代对象,然后会针对情况,迭代的形式不同。
如果是字符串的元组,第一次迭代的话,每次得到一个字符串,如果再嵌套一个for循环的话,每一次就得到一个字符,这个就是union中的逻辑。
def union(*args):
res=[]
for seq in args:
for x in seq:
if not x in res:
res.append(x)
return res
def intersect(*args):
res=[]
for x in args[0]: #对s1中的字符进行迭代
for other in args[1:]: #对除第一项外的项进行迭代,一次一个元组
if x not in other: break #判断s1中的字符是否在s2中。
else:
res.append(x)
return res
>>> import sys
>>> sys.path.append("/home/ryu/programming/python")
>>> from inter2 import union,intersect
>>> (s1,s2,L1,L2)=('spam','scan',[1,2,3],(1,4))
>>> intersect(s1,s2),union(s1,s2)
(['s', 'a'], ['s', 'p', 'a', 'm', 'c', 'n'])