python文档中关于默认参数是这样说的:
Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call.
因此,如下代码:
def function(data=[]):
print id(data), data
data.append(1)
for i in range(3):
function()
输出结果为:
4462873272 []
4462873272 [1]
4462873272 [1, 1]
一切正像文档中说的那样,data只计算一次,之后的调用返回的是已经计算出来的值(因此,id(data)没有变化,每次append均针对同一个data)。
但是我们带参数调用function时,即:
for i in range(3):
function([])
输出结果为:
4462872984 []
4462872984 []
4462872984 []
data的值是符合预期的,但是三次调用function,id(data)的值竟然也一样,这个是为什么呢?带参数传递时,每次调用都应该是新建data的吧。
PHP中文网2017-04-17 13:39:41
认真读文档啊:https://docs.python.org/2/library/functions.html#id 。
Because:
Two objects with non-overlapping lifetimes may have the same id() value.
CPython中id的实现概念上相当于对象在内存中的地址。那请看这段代码:
id([])
# then it destory
id([])
# then its memory reused
前后是两个不同的list对象,但既然前面一个对象用完就被销毁掉了,那后面的一个list就可能重用相同的内存空间,所以id返回的地址就是一样的了。
巴扎黑2017-04-17 13:39:41
虽然不明白最后到底有没有回答到问题深处, 但如果这个答案能帮助有的同学对参数的疑惑 也是好的.
前一阵子我也是刚学python, 看到关于默认参数列表的一部分, 说一下我的理解.
当调用函数f() 连续三次时,
第一次 f() 会找到默认参数 data = []
而且它在内存中中的地址是能通过 类似 'f.data' 寻址的.
接下来再次调用 f() 会重复以上操作, 因为没有输入一个新的参数, 会默认还是找到之前的data作为此次参数列表.
def f(data = []):
data.append("end")
print data
f()
执行前 data = []
执行后 默认参数变为 data =['end']
f()
重复上次操作 这里data 可以理解为该函数的一个成员变量
另外 也可以调用 f.defaults 这个属性来查看函数f当前情况的默认参数是什么
比如 定义完f后,
# 定义完f后的默认参数
print f.__defaults__
#>>([],)
# f() 执行后的默认参数
print f.__defaults__
#>>(['end'],)
所以默认参数在前后几次 f()执行过程中是可变的.
而如果调用f([]) 的话 是不会对默认参数产生影响的,
print f.__defaults__
f([])
print f.__defaults__
f([])
print f.__defaults__
如果有兴趣还可以尝试一下 对
f(data = [] ) 进行迭代 :)
可以参考这里 觉得讲的很清楚 Python 中函数的参数
ringa_lee2017-04-17 13:39:41
这个问题是这样子的...
这是算是python比较高级的内容了吧..初学者基本上都会碰到这个问题
函数的内省导致了,你的参数是函数类型的一个属性(虽然没办法用.
来访问).
这也就是意味着,你在定义函数的时候,你的参数已经成了这个函数对象的一部分了..类似于:
class cls():
A = []
a = cls()
b = cls()
a.A.append("a")
print b.A
你可以发现有刚刚的"a"
被打印出来了..
函数这边也是一样的.定义的参数属性是共享的
但是以上规则仅仅针对于可变数据类型类型,比如列表
因为不可变数据类型不是在当前这个内存块里面修改的...而是指向了另外一个内存块..
两个python特性:
动态类型的意思是:你的变量只是一个类似于指针的东西.只不过他可以随便乱指...他指向的是一个类型.这个类型可以是整型,字符串,类等等.
你的一个变量可以更换指向的类型.比如:a = 1
中a
指向的是一个整型类型.这个整型类型的值是1
(当然还有其他一些组成部分,比如还有count和类型声明等等)
但是当你从新指向的时候,比如:a = "hello world"
,那么发生的事情是,a
这个变量指向了一个字符串类型,而之前1
这个整型发生的变化是count-1,等count为0了内存才被回收.
这就是传说中的动态类型
函数在python中也是类型.
比如你
def foo(a, b):
pass
那么就是生成了一个函数类型,赋值给foo这个变量了..
而这个类型中所有东西都可以通过域操作符 .
来操作.