免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3927 | 回复: 6
打印 上一主题 下一主题

关于python默认参数的问题。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-18 23:57 |只看该作者 |倒序浏览
下面是python文档里的代码,有一些不明白之处,希望各位指点。

version 1:

  1. def f(a, L=[]):
  2.     L.append(a)  
  3.     return L

  4. print(f(1))
  5. print(f(2))            # 调用时函数参数 L 会保留上次的值。
  6. print(f(3))
复制代码
version 2:

  1. def f(a, L=None):
  2.     if L is None:     # 但是这里,若以同样的调用方式,在进入函数体后 L 总会还原成 None,为什么上一个版本的 L 不会还原成 [] 呢?
  3.         L = []
  4.     L.append(a)
  5.     return L
复制代码

论坛徽章:
0
2 [报告]
发表于 2010-08-19 08:26 |只看该作者
唉,好冷清。
gamcat 该用户已被删除
3 [报告]
发表于 2010-08-19 09:05 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
4 [报告]
发表于 2010-08-19 09:05 |只看该作者
回复 1# Vegertar

这个好像是因为默认参数的赋值只在函数定义时发生一次,记不得在哪儿看得了。你可以比较一下
  1. def f(a, L=[]):
  2.     L.append(a)
  3.     return L,id(L)
  4. print  f(1)
  5. print  f(2)         
  6. print  f(3)

  7. print '*******'

  8. def F(a):
  9.     def f(a, L=[]):
  10.         L.append(a)
  11.         return L,id(L)
  12.     return f(a)
  13. print  F(1)
  14. print  F(2)         
  15. print  F(3)
复制代码

论坛徽章:
0
5 [报告]
发表于 2010-08-19 10:18 |只看该作者
f的默认参数是f.func_defaults,多打印几下就清楚了

论坛徽章:
0
6 [报告]
发表于 2010-08-19 10:20 |只看该作者
对于非数值类型的默认参数,只会在第一次调用时进行求值(取地址)操作,后面的所有调用都发生在同一个位置的对象上。只有字符串类型不受此限制,因为string本身是不可变的(immutable)的,每一次修改它都会创建一个新的对象。

按照luffy.deng的方法,你可以打印出L的id,这样就比较清楚了。

或者你用下面的代码来看看:

  1. def f(a, L=[]):
  2.     L.append(a)
  3.     print("L = {0} and the L's id is {1}".format(L,id(L)))
  4.     return L

  5. def F(a, L=None):
  6.     if L is None:
  7.         L = []
  8.     L.append(a)
  9.     print("L = {0} and the L's id is {1}".format(L,id(L)))
  10.     return L

  11. def main():
  12.    print 'f(1):  ', f(1)
  13.    print 'f(2, [3]):  ', f(2, [3])
  14.    print 'f(4):  ', f(4)
  15.    print 'f(5, [6]):  ', f(5, [6])
  16.    print 'f(7):  ', f(7)
  17.    print 'F(1):  ', F(1)
  18.    print 'F(2,[3]):  ', F(2,[3])
  19.    print 'F(4):  ', F(4)
  20.    print 'F(5, [6]):  ', F(5, [6])

  21. if __name__ == '__main__':
  22.     main()
复制代码
f(1):   L = [1] and the L's id is 140296258680304    #可以看到,当不指定L的值时,使用默认参数,L的id是304
[1]
f(2, [3]):   L = [3, 2] and the L's id is 140296258100832   #当指定L的值为[3]时,地址变成了832
[3, 2]
f(4):   L = [1, 4] and the L's id is 140296258680304    #可以看到,当不指定L的值时,使用默认参数,L的id是304, 所以再计算f(4)的时候,就会结果就是[1, 4]
[1, 4]
f(5, [6]):   L = [6, 5] and the L's id is 140296258100832
[6, 5]
f(7):   L = [1, 4, 7] and the L's id is 140296258680304
[1, 4, 7]
F(1):   L = [1] and the L's id is 140296258100832
[1]
F(2,[3]):   L = [3, 2] and the L's id is 140296258100832
[3, 2]
F(4):   L = [4] and the L's id is 140296258100832
[4]
F(5, [6]):   L = [6, 5] and the L's id is 140296258100832
[6, 5]

论坛徽章:
0
7 [报告]
发表于 2010-08-19 10:40 |只看该作者
基本上明白了,谢谢诸位!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP