这个世界其实从不曾有一个人能取代另一个人的位置,所谓的取代,只是以前的那个人被遗忘了。
普通传参的小坑
def test(a=[]):
a.append('A')
return a
print test()
print test()
print test()
返回的结果:
['A']
['A', 'A']
['A', 'A', 'A']
原因:传入的参数是一个空的列表,Python遇到函数的时候会把函数读到内存中,默认参数会被创建。虽然函数没有执行,但是其中赋值创建变量,并且创建好了。a始终没有改变,指向的内存方向都是同一个内存。
使用id()可以查看函数内部在内存中的地址。
def test(a=[]):
a.append('A')
print id(a)
return a
print test()
print test()
print test()
返回结果:
53854536
['A']
53854536
['A', 'A']
53854536
['A', 'A', 'A']
可以看到指向内存的位置都没变。
这里引申一下Python的可变对象和不可变对象,dict,list是可变对象,str,int,tuple,float是不可变对象。意思就是可变对象的值改变后对应的内存地址没改变。但是不可变对象改变数值后,就会创立一个新的对象并且占用新的内存空间。所以一般如果想要把一个列表的所有元素拼接成一个字符串的话,遍历这个列表没然后使用’’.join()方法,节省内存。
如果想要每次都是变成空的列表可以这样写。
def test_new(a=None):
if a is None:
a=[]
a.append('A')
print id(a)
return a
print test_new()
print test_new()
print test_new()
记住,对应的内存地址任然是一样的。
返回结果:
51934344
['A']
51934344
['A']
51934344
['A']
动态参数
Python的动态参数有*args与**kwargs。 *args表示任何多个无名参数,它是一个tuple。**kwargs表示关键字参数,它是一个dict。
*args的用法
def fun(*args):
for x in args:
print x
fun(1,2,3)
返回结果:
1
2
3
当然还可以传入列表,但是传入列表的时候必须要在前面加上*号。比如:
li=[1,2,3,4,5]
fun(*li)
返回结果:
1
2
3
4
5
**kwargs的用法
def fun_test(**kwargs):
for x in kwargs:
print x,kwargs[x]
fun_test(k1=1,k2=[1,2,3])
返回结果:
k2 [1, 2, 3]
k1 1
当然还可以传入字典,使用方法和上面一致,也是加上两个*号。