这个世界其实从不曾有一个人能取代另一个人的位置,所谓的取代,只是以前的那个人被遗忘了。

普通传参的小坑

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

    当然还可以传入字典,使用方法和上面一致,也是加上两个*号。