其实也不能说是陷阱,只是一个不容易注意到的地方,尤其是有其他java/c++类编程语言经验的人员,这里涉及到python的一个特点,所以笔者说是陷阱只是一个噱头而已。

def test(item, buf = []):
buf.append(buf)
print buf

非常简单的一个函数,功能非常简单,现在看下面的调用代码

test('younger')
test('shen')

输出:

['younger']
['younger', 'shen']

该函数初衷是希望当没有提供默认的buff参数的时候,建立一个空的列表,然后把一个对象添加到该列表中,并且打印, 但是程序的执行似乎并没有按照我们的意图来执行,似乎每个函数都共享了buff,但是我们明明每次都在参数列表中初始化了buff变量,分析如下:

python中的def语句在每次执行的时候都初始化一个函数对象,这个函数对象就是我们要调用的函数,可以把它当成一个一般的对象,只不过这个对象拥有一个可执行的方法和部分属性,对于参数中提供了初始值的参数,由于python中的函数参数传递的是对象,也可以认为是传地址,只有def的时候初始化一次,然后在调用者和被调用者中都是共享的,所以在 func.func_defaults中只能看到一个默认参数,在该函数对象被初始化的时候就已经存在了。

解决这个问题可以用这个方法

def test(item, buf = None):
if buf is None:
buf = []
buf.append(item)
print buf

这样在不给定buf参数的时候可以初始化一次buf,每次都是新的,所以不会出现上面的陷阱,其实这里的None只是占位符而已,用空[]也可以,只不过要需要这样写

def test(item, buf = []):
if len(buf) < 1:
buf = []
buf.append(item)
print buf

这样也可以解决问题,只是看起开不太好而已。

近期除了使用django进行web开发之外,打算重新开始学习linux和操作系统的东西,近期会制定学习计划开始执行。

python中函数的默认参数陷阱问题的更多相关文章

  1. Python中list作为默认参数的陷阱

    在Python中,作为默认参数的一定要是不可变对象,如果是可变对象,就会出现问题,稍不注意,就会调入陷阱,尤其是初学者,比如我(┬_┬). 我们来看一个例子. def add(L=[]): L.app ...

  2. python定义函数时默认参数注意事项

    如果在调用一个函数时,没有传递默认参数,则函数内的默认参数是对函数的默认参数属性__defaults__的引用, 如 def func(arg1=[]): arg1.append(2) 调用func时 ...

  3. C++中函数的默认参数

    使用方法: (1)在函数声明或定义时,直接对参数赋值,该参数就是默认参数. (2)在函数调用时,省略部分或全部参数,这时就会使用默认参数进行代替. 注意事项: (1)一般在声明函数是设置默认参数. 如 ...

  4. 在python中,用默认参数(list,set,dict...)时要小心

    在我们平时写需求的时候,如果没有了解到以下知识点,可能会出现这样的问题,掉进坑里面,甚至很难找到问题的根源.下面我们来看看使用可变默认参数(Mutable default arguments)时会出现 ...

  5. C++中函数的默认参数和C语言中volatile的学习

    1.函数默认参数 1 int func(int a,int b=10) 2 { 3 return a*b; 4 } 5 6 int main() 7 { 8 int c=func(2); 9 cout ...

  6. Python 中函数的 收集参数 机制

    定义函数的时候,在参数前加了一个 * 号,函数可以接收零个或多个值作为参数.返回结果是一个元组. 传递零个参数时函数并不报错,而是返回一个空元组.但以上这种方法也有局限性,它不能收集关键字参数. 对关 ...

  7. c++中 函数的默认参数 学习

    默认参数指的是当函数调用中省略了实参时     自动使用一个默认的值. 对于带参数列表的函数,必须从右向左添加默认值  (就是说她的右边肯定是先有默认的值) fun(int ,1,2,3) 不能 fu ...

  8. 【转】Python函数默认参数陷阱

    [转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...

  9. Python面试题目之Python函数默认参数陷阱

    请看如下一段程序: def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) list2 = extend_l ...

随机推荐

  1. kafka在zookeeper中的存储结构

    参考site:http://kafka.apache.org/documentation.html#impl_zookeeper 1.zookeeper客户端相关命令 在确保zookeeper服务启动 ...

  2. How To Create a New User and Grant Permissions in MySQL

    How to Create a New User Let’s start by making a new user within the MySQL shell: CREATE USER 'newus ...

  3. Servlet线程安全

    public class servletDemo1 extends HttpServlet { int i=0; public void doGet(HttpServletRequest reques ...

  4. 【bzoj3514】Codechef MARCH14 GERALD07加强版

    hzwer上少有的几道需要建一下模的 要不是有这么几道题 我都觉得lct只会考裸题了呢 题解看hzwer吧 http://hzwer.com/4358.html 唯一蛋疼的就是为了处理0这个呵呵的位置 ...

  5. 【算法与数据结构】在n个数中取第k大的数(基础篇)

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍            在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些 ...

  6. Deme_遥感控制物体移动(涉及遮罩,小摄像机跟随)

    using UnityEngine; using System.Collections; using UnityEngine.EventSystems; public class JoyControl ...

  7. [Angular 2] Using Pipes to Filter Data

    Pipes allow you to change data inside of templates without having to worry about changing it in the ...

  8. Android Touch系统简介(二):实例详解onInterceptTouchEvent与onTouchEvent的调用过程

    上一篇文章主要讲述了Android的TouchEvent的分发过程,其中有两个重要的函数:onInterceptTouchEvent和onTouchEvent,这两个函数可被重装以完成特定的逻辑.on ...

  9. 刨根问底:对于 self = [super init] 的思考

    对象初始化有两种方式:[class new] 与 [[class alloc] init] 对于后者,有分配和初始化的过程,alloc 从应用程序的虚拟地址空间上为该对象分配足够的内存,并且将新对象的 ...

  10. python文件处理--笔记

    之前一段时间一直在忙着写毕业论文,盲评搞得人心惶惶,以致于都没有看书,最近需要补上前面落下的东西. <Python3程序开发指南> 1.二进制数据的读写 二进制格式通常是占据磁盘空间最小. ...