最近在写代码时发现一个有趣的地方,当python中的函数使用list作为默认参数且调用时不给其赋值时,无法通过在函数中将其赋值为[]来达到清空此默认参数的目的。按照道理来说,函数f1中的list为局部变量,在下次进入时,其应保持默认值才对。而且list具有可变性,在原内存地址中修改其内容。

具体代码如下:

def f1(a=[2]):
a.append(100)
print a
a=[]
#del a[:]
print a def f2(a=[2]):
a.append(100)
print a
#a=[]
del a[:]
print a def f3(b):
b.append(100)
print b
b=[]
print b print 'f1 result:'
for i in range(2):
f1() print 'f1 result when give parameter:'
for i in range(3):
c=[9]
f1(c) print 'f2 result:'
for i in range(4):
f2() print 'f3 result:'
for i in range(5):
d=[8]
f3(d)

运行结果如下:

f1 result:
[2, 100]
[]
[2, 100, 100]
[]
f1 result when give parameter:
[9, 100]
[]
[9, 100]
[]
[9, 100]
[]
f2 result:
[2, 100]
[]
[100]
[]
[100]
[]
[100]
[]
f3 result:
[8, 100]
[]
[8, 100]
[]
[8, 100]
[]
[8, 100]
[]
[8, 100]
[]

 自己想了个可能的答案。(当python中的函数使用list作为默认参数且调用时不给其赋值时)在f1()中,list a在内存空间中指向[2]。执行a.append(100)后,list a指向的内存空间不变,内容变为[2,100]。执行a=[]后,list a指向的空间变了,其内容为[]。当再次进入f1()时,list a又指向了原来的内容空间,即内容为[2,100]。所以,当执行a.append(100)后,list a指向的内存空间不变,内容变为[2,100,100]。为了验证我的猜想,修改了下代码:

def f1(a=[2]):
a.append(100)
print a,
print id(a)
a=[]
#del a[:]
print a,
print id(a) def f2(a=[2]):
a.append(100)
print a,
print id(a)
#a=[]
del a[:]
print a,
print id(a) def f3(b):
b.append(100)
print b,
print id(b)
b=[]
print b,
print id(b) print 'f1 result:'
for i in range(2):
f1() print 'f1 result when give parameter:'
for i in range(3):
c=[9]
f1(c) print 'f2 result:'
for i in range(4):
f2() print 'f3 result:'
for i in range(5):
d=[8]
f3(d)

结果为:

f1 result:
[2, 100] 12299240
[] 12338960 #the address is different
[2, 100, 100] 12299240
[] 12338960
f1 result when give parameter:
[9, 100] 12338960
[] 12339040
[9, 100] 12339040
[] 12338960
[9, 100] 12338960
[] 12339040
f2 result:
[2, 100] 12299320
[] 12299320  #the address is the same
[100] 12299320
[] 12299320
[100] 12299320
[] 12299320
[100] 12299320
[] 12299320
f3 result:
[8, 100] 12339040
[] 12337280
[8, 100] 12337280
[] 12339040
[8, 100] 12339040
[] 12337280
[8, 100] 12337280
[] 12339040
[8, 100] 12339040
[] 12337280

  

python中使用list作为默认参数且调用时不给其赋值的问题的更多相关文章

  1. Python之在函数中使用列表作为默认参数

      本文将介绍笔者在工作中遇到的Python的一个坑,那就是使用列表作为默认参数.   我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使 ...

  2. python函数中的位置参数、默认参数、关键字参数、可变参数区别

    一.位置参数 调用函数时根据函数定义的参数位置来传递参数. #!/usr/bin/env python # coding=utf-8 def print_hello(name, sex): sex_d ...

  3. Python在函数中使用列表作为默认参数

    在学习中遇到的Python的一个坑,那就是使用列表作为默认参数. 我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使用列表作为函数的默认参 ...

  4. python 中为什么不需要重载 参数*arg和**args

    函数重载主要是为了解决两个问题. (1)可变参数类型. (2) 可变参数个数. 另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两 ...

  5. Python中的函数及函数参数的使用

    函数:一个工具,随调随用 降级代码冗余 增加代码的复用性,提高开发效率,为了不成为cv战士 提高程序扩展性 函数有两个阶段:定义阶段,调用阶段. 定义时:只检查函数体内代码语法,不执行函数体内代码. ...

  6. Python基础之定义有默认参数的函数

    1. 构建有默认参数的函数 当我们在构建一个函数或者方法时,如果想使函数中的一个或者多个参数使可选的,并且有一个默认值,那么可以在函数定义中给参数指定一个默认值,并且放到参数列表的最后就行了.比如: ...

  7. Python中方法的缺省参数问题分析

    引言: 在Python中可以缺省给方法制定缺省值,但是这个缺省值在某些情况下确是和我们预期不太一致的-... 这个诡异的问题,曾经困然了我几天时间,才最终定位出来-.. 测试代码 from datet ...

  8. redux中createStore方法的默认参数

    一般使用方法: createStore(reducer, applyMiddleware(thunk)) 传递默认参数: createStore(reducer, defaultState, appl ...

  9. python中sort()方法的cmp参数

    <python基础编程>里有讲到一段高级排序: “如果希望元素能按照特定的方式进行排序(而不是sort函数默认的方式,即根据python的默认排序规则按升序排列元素,第5章内对此进行讲解) ...

随机推荐

  1. oracle sql语句跟踪

    select b.SQL_TEXT,b.FIRST_LOAD_TIME,b.SQL_FULLTEXT    from v$sqlarea b    order by  b.FIRST_LOAD_TIM ...

  2. Jquery 设置style:display 通过ID隐藏区域

    $("#id").css('display','none'); $("#id").css('display','block'); 或 $("#id&q ...

  3. C++ STL算法系列6---copy函数

    现在我们来看看变易算法.所谓变易算法(Mutating algorithms)就是一组能够修改容器元素数据的模板函数,可进行序列数据的复制,变换等. 我们现在来看看第一个变易算法:元素复制算法copy ...

  4. ChromePHP - Chrome浏览器下的PHP debug工具

    一款 Chrome 下用来配合调试 PHP 的工具,看官方介绍应该和 FirePHP 有异曲同工的.喜欢用Chrome 的PHPer 可以尝试一下. 官方网站:http://www.chromephp ...

  5. ansible控制windows的官方翻译

    Ansible控制windows 1.    Windows下如何工作 在ansible控制linux的时候,用的是ssh的方式,在windows中,使用的是power shell,在客户端机器上也是 ...

  6. Intent相关

    Intent是什么? 翻译为:意图,目的(名词) 其实根本没必要管它是什么,看看它能做什么就好了. 不过后来我知道了,它就是个机制----通信机制-----android的许多组件间的交流要依赖它. ...

  7. 50+ 响应式的Prestashop电商主题

    PrestaShop是一款针对web2.0设计的全功能.跨平台的免费开源电子商务解决方案,自08年1.0版本发布,短短两年时间,发展迅速,全球已超过四万家网店采用Prestashop进行部署.Pres ...

  8. 项目 erlang启动时死循环

    机子里的otp是新装的 看了一下main 是在util:ensure_started一堆app的时候死讯了, 按照顺序是sasl crypto asn1 public_key ssl 发现是publi ...

  9. javascript面向对象事件继承

    继承:父类有的,子类也有.父类改变,子类也跟着变. 属性继承:      矫正this (window对象,矫正成object对象)     fn .call(this是谁,参数1,参数2...); ...

  10. js冲突

    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(//"~/Scripts/modernizr-2.6.2 ...