默认参数的坑

定义一个函数,传入一个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. php 抽象类 静态 单体设计模式

    php oop----抽象类 抽象类机制使得子类可共用基类的某些信息,具体细节会留给子类,典型用在这样情形中,抽象类并不定义全部的方法,部分方法的实现推迟到子类继承抽象类时.它是介于接口和具体类间的一 ...

  2. 虚拟机性能监控与故障处理工具------JDK的命令行工具

    ①jps:虚拟机进程状况工具 功能:列出正在运行的虚拟机进程,并显示1.虚拟机执行主类名称以及2.这些进程的本地虚拟机唯一ID(LVMID). 使用频率最高的JDK命令行工具,其他的JDK工具大多需要 ...

  3. Redis管道理解

    Redis管道理解 简介 管道并不是Redis本身提供的功能,通常是客户端提供的功能: 管道就是打包多条无关命令批量执行,以减少多个命令分别执行消耗的网络交互时间(TCP网络交互),可以显著提升Red ...

  4. CentOS 7 下 RabbitMQ 集群搭建

    环境 10.0.0.20 node1 10.0.0.21 node2 10.0.0.22 node3 搭建(在所有节点执行) 添加EPEL源 [root@node1 ~]# rpm -Uvh http ...

  5. Saltstack 分发

    把master上的hosts文件分发到所有主机 [root@node1 ~]# salt-cp '*' /etc/hosts /etc

  6. webstorm安装教程

    之前有些一些破解的,但是独独忘记了安装的这个教程,现在补上:见下: 先来一官方的解释:WebStorm是JetBrains 推出的一款强大的HTML5编辑工具,拥有丰富的代码快速编辑,可以智能的补全代 ...

  7. .net core 3.0视图动态编译

    之前在使用Visual Studio 2019的时候,就发现asp.net 3.0中没有cshtml动态编译的功能了:也就是说,如果改了cshtml,刷新页面不会立即生效,而是要重新编译一次才行. 这 ...

  8. API判断本机安装的Revit版本信息

    start [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class c ...

  9. 加密入门(三):TrueCrypt(转)

    http://terrychen.info/encryption-truecrypt/ TrueCrypt 是一款功能强大的开源加密工具,利用 TrueCrypt 可以创建一个加密文件作为虚拟加密卷, ...

  10. 结巴分词和自然语言处理HanLP处理手记

    手记实用系列文章: 1 结巴分词和自然语言处理HanLP处理手记 2 Python中文语料批量预处理手记 3 自然语言处理手记 4 Python中调用自然语言处理工具HanLP手记 5 Python中 ...