zoukankan      html  css  js  c++  java
  • python中函数的默认参数陷阱问题 C

    其实也不能说是陷阱,只是一个不容易注意到的地方,尤其是有其他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和操作系统的东西,近期会制定学习计划开始执行。

  • 相关阅读:
    了解HTTP Header之User-Agent和HTTP协议的响应码
    怎样才算一个优秀的管理者
    ldpi、mdpi、hdpi、xhdpi、xxhdpi (无内容,待填)
    手把手教做小偷采集
    java中碰到无法解决的问题:无法访问类的getter访问器
    简单的加密解密处理
    Java中处理二进制移位
    Java中实现String.padLeft和String.padRight
    这短短几行代码价值一万
    从一篇文章中检查特定单词出现数量和第一次出现位置
  • 原文地址:https://www.cnblogs.com/youngershen/p/3978332.html
Copyright © 2011-2022 走看看