Python默认参数调用疑惑,python参数疑惑,python文档中关于默
Python默认参数调用疑惑,python参数疑惑,python文档中关于默
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的吧。
同意ls
LZ请注意常量与变量的区别, 你想要个不同的id, 得用list()。
前一阵子我也是刚学python, 看到关于默认参数列表的一部分, 说一下我的理解.
当调用函数f() 连续三次时,
第一次 f() 会找到默认参数 data = []
而且它在内存中中的地址是能通过 类似 'f.data' 寻址的.
接下来再次调用 f() 会重复以上操作, 因为没有输入一个新的参数, 会默认还是找到之前的data作为此次参数列表.
def f(data = []): data.append("end") print data
f()
f()
另外 也可以调用 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 中函数的参数
认真读文档啊:https://docs.python.org/2/library/functions.html#id 。
Because:
CPython中id的实现概念上相当于对象在内存中的地址。那请看这段代码:
id([])# then it destoryid([])# then its memory reused
前后是两个不同的list对象,但既然前面一个对象用完就被销毁掉了,那后面的一个list就可能重用相同的内存空间,所以id返回的地址就是一样的了。
这个问题是这样子的...
这是算是python比较高级的内容了吧..初学者基本上都会碰到这个问题
好了,正文开始
函数的内省导致了,你的参数是函数类型的一个属性(虽然没办法用.来访问).
这也就是意味着,你在定义函数的时候,你的参数已经成了这个函数对象的一部分了..类似于:
class cls(): A = []a = cls()b = cls()a.A.append("a")print b.A
你可以发现有刚刚的"a"被打印出来了..
函数这边也是一样的.定义的参数属性是共享的
但是以上规则仅仅针对于可变数据类型类型,比如列表
因为不可变数据类型不是在当前这个内存块里面修改的...而是指向了另外一个内存块..
扩展阅读:
两个python特性:
1. python的动态类型问题:
动态类型的意思是:你的变量只是一个类似于指针的东西.只不过他可以随便乱指...他指向的是一个类型.这个类型可以是整型,字符串,类等等.
你的一个变量可以更换指向的类型.比如:a = 1中a指向的是一个整型类型.这个整型类型的值是1(当然还有其他一些组成部分,比如还有count和类型声明等等)
但是当你从新指向的时候,比如:a = "hello world",那么发生的事情是,a这个变量指向了一个字符串类型,而之前1这个整型发生的变化是count-1,等count为0了内存才被回收.
这就是传说中的动态类型
2. 函数的内省
函数在python中也是类型.
比如你
def foo(a, b): pass
那么就是生成了一个函数类型,赋值给foo这个变量了..
而这个类型中所有东西都可以通过域操作符 . 来操作.
编橙之家文章,
相关内容
- Django学习遇到瓶颈要如何继续学习,django瓶颈,RT,目前
- python class中的self _init_(self,param1,param2)怎么回事?,p
- Python switch case实现操作是怎样的,pythonswitch,Python里怎么
- Python模拟登录cookie有验证码要怎么做才能抓到内容,
- python html兼容空格问题,pythonhtml兼容空格,文本框里输入
- Python django监测用户跳转页面状态求思路,pythondjango,d
- 求python访问网页并提交请求的操作思路,python思路,我要
- 求助python django-pagination分页url显示方式问题,,django-p
- 新手求Python高手看源码错误,python源码,num=10;print
- python requests库登录网站失败求分析脚本,pythonrequests,想
评论关闭