默认参数的坑

定义一个函数,传入一个list,添加一个end再返回

def  add_end(L=[]):
L.append('END')
return L

正常调用时,结果似乎不错

print  add_end([1,2,3])  #[1, 2, 3, 'END']

使用默认参数调用时,一开始结果也是对的,但是再次调用时,结果就不对了

print add_end()   #['END']

print add_end()    #['END', 'END']

print  add_end()    #['END', 'END', 'END']

从上述调用结果发现,函数每次都记住了上次添加了‘END’后的list,python函数在定义的时候,默认参数L的值就被计算出来了即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变 了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了

所以,定义默认参数要牢记一点:默认参数必须指向不变对象

修改上面的例子,可以用None这个不变对象来实现

def  add_end2(L=None):
if L is None:
L=[]
L.append('END')
return L

无论调用多少次都没问题

print add_end2()
print add_end2()
print add_end2()
#['END']
#['END']
#['END']

不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。

不可变(immutable):int、字符串(string)、float、(数值型number)、元组(tuple)
可变(mutable):字典型(dictionary)、列表型(list)

Python默认参数的坑的更多相关文章

  1. 笔记:Python 默认参数必须指向不变对象

    笔记:Python 默认参数必须指向不变对象 学习记录 >>> def add_end(L=[]): L.append('END') return L >>> ad ...

  2. python之函数默认参数的坑

    坑 当你的默认参数如果是可变的数据类型,你要小心了 例题 # 正常没毛病的操作 def func(a,b=False): print(a) print(b) func(1,True) # 在实参角度, ...

  3. python默认参数陷阱

    对于学习python的人都有这样的困惑 def foo(a=[]): a.append(5) return a Python新手希望这个函数总是返回一个只包含一个元素的列表:[5].结果却非常不同,而 ...

  4. C#函数的默认参数——填坑记

    昨天踩了一个坑.默认参数 + 增量发布的坑. 过程是这样的. 1. 有一个底层的方法,格式形如 void Test<T>(int p1, string p2, Func<T> ...

  5. Python 默认参数

    定义默认参数 定义函数的时候,还可以有默认参数. 例如Python自带的 int() 函数,其实就有两个参数,我们既可以传一个参数,又可以传两个参数: >>> int('123') ...

  6. python默认参数不能定义为可变对象类型

    python的默认参数只会在函数定义时被确定,而不是每次调用时重新确定,所以,一旦在函数中修改了默认参数,则在随后的调用中都会生效 由于这个特性,在定义函数时,如果默认参数使用可变的对象类型,如空列表 ...

  7. Python默认参数

    在python函数中, 可以使用如下方式声明并初始化参数 def to_smash(total_candies, n_friends=3): """Return the ...

  8. Python - 默认参数传参陷阱

    def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) print(list1) # [10] list2 ...

  9. python默认参数问题

    我们在定义默认参数时,有时会遇到一写似乎难以理解的问题.比如,在第二次调用函数时,默认参数记住了上一次执行的结果: >>> def test(L=[3,]): ... L.appen ...

随机推荐

  1. 设备树中ranges属性分析(1)

    作者 彭东林 pengdonglin137@163.com   软件环境 Linux-4.10.17 Qemu+vexpress   概述 在设备树中有时会看到ranges属性,这个ranges属性可 ...

  2. AngularJS中有关Directive的汇总

    本篇通过几个例子对AngularJS中的Directive进行汇总. 例子1,单向绑定和双向绑定 <html ng-app="myApp"> <head> ...

  3. stm32型号解读

      ST意法半导体在牵手ARM后可以说是做的非常成功,抓住了从普通MCU到ARM的市场转变的机会.由于ST公司的STM32系列ARM 使用了完善的库开发,作为芯片的应用者不用从底层的寄存器来实现每个功 ...

  4. Spark机器学习(4):朴素贝叶斯算法

    1. 贝叶斯定理 条件概率公式: 这个公式非常简单,就是计算在B发生的情况下,A发生的概率.但是很多时候,我们很容易知道P(A|B),需要计算的是P(B|A),这时就要用到贝叶斯定理: 2. 朴素贝叶 ...

  5. 关于 TVM

    偶然间对 arm 中 mali 显示核心感兴趣,找到的 TVM.将了解到的信息做个备忘. TVM 是 Tensor Virtual Machine 的所写? 官网上,TVM 定义自己为一种 Inter ...

  6. ASP.net教程]启用WebApi 2里的Api描述信息(Help下的Description

    环境:vs2013+web api 2 问题:默认情况下新建的Web Api 2项目,自带的Help页下会显示Api的相关信息,但Description那一栏无法获取到数据,如下图所示: 解决: 1. ...

  7. Linux编译步骤概述

    Linux,一切皆文件! linux环境下,编译源码文件步骤总结 01.下载解压 一遍在开源网站有download/下载页面 02.安装基本编译环境 yum install -y gcc gcc-c+ ...

  8. 一起SQL引发OOM的解决思路与过程(转载)

    在TOMCAT WEB程序的运行过程中,突然触发了内存溢出错误,检查Tomcat的localhost日志,找到如下信息: java.lang.OutOfMemoryError: Java heap s ...

  9. easyui-switchbutton js判断是否启动

    <input class="easyui-switchbutton" id="statusId" name="status" onTe ...

  10. SNF快速开发平台MVC-EasyQuery-拖拽生成SQL脚本

    在之前介绍一下EasyQuery工具SNF开发平台WinForm-EasyQuery统计分析-效果-非常牛逼的报表查询工具 Winform开发框架之图表报表在线设计器-报表-SNF.EasyQuery ...