Python函数后面的参数可以跟实例化的对象是同一个吗?参数可以单独拿出来使用?

Python010

Python函数后面的参数可以跟实例化的对象是同一个吗?参数可以单独拿出来使用?,第1张

在Python中,万物皆对象函数也是一个对象,也可以作为参数传递给别的函数。

foo这只是一个标识符,它可以指向任何东西,包括变量、类、函数、模块、流等。timer是一个返回函数的高阶函数,它的返回值是一个函数,赋值给foo之后,foo也就是一个函数。

这个问题的答案无外乎这几种说法:传值,传引用,对于可变对象是传引用,不可变对象是传值。

传引用

先看下面这个例子:

>>>def foo(n):

... print id(n)

... n = 3

... print id(n)

>>>n = 2

>>>id(n)

31030000L

>>>foo(n)

31030000L

31029976L

>>>n

2

>>>id(n)

31030000L

由foo中两次输出不相等可以看出,传引用说法并不成立。

传值

来看下面的例子:

>>>def foo(n):

...print n

...n.append(3)

...print n

>>>n = [1, 2, 4, 8]

>>>foo(n)

[1, 2, 4, 8]

[1, 2, 4, 8, 3]

>>>n

[1, 2, 4, 8, 3]

按传值的说法,一个值传进来,在函数内改动并不会影响变量本身的值,上面例子中n变量本身的值也被改变了,说明传值的说法也不对。

3.可变对象传引用,不可变对象传值

相比上面两种说法,这种说法似乎更靠谱,传播也更为广泛,那它到底对不对呢?

>>>def foo(n):

...print id(n)

...n = ['1', '2', '3']

...print id(n)

...print n

>>>n = [1,2,3,4,5,6]

>>>id(n)

35637576

>>>foo(n)

35637576

35916168

['1', '2', '3']

>>>n

[1, 2, 3, 4, 5, 6]

按照可变对象传引用的说法,上面list类型是可变对象,应该传引用,这foo方法中两次调用id应该输出一样的值,更改的结果也应该影响到外部变量,但结果显然不是这样的,这说明,这种说法也是不正确的。

那么Python传值的方法到底是什么样呢?其实Python中的函数参数所遵循的是传对象(call by object),或者叫做穿对象的引用(call by object reference)。在调用函数时,将变量整个对象传入,对于可变对象的修改,在函数内外均可见;而对于不可变对象,因为其并不能真正意义上被赋值,修改是通过生成新的对象来实现的。

下面来一个有趣的例子作为结尾:

>>>def bar(a = []):

...print id(a)

...a.append(7)

...print a

>>>for _ in range(5):

...bar()

#结果输出请自己动手实践,原因应该不难理解