前言

pass

正文

https://docs.python.org/3/tutorial/controlflow.html#default-argument-values 中,有这样一段话

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

大致意思为

重要警告:默认值仅计算一次。 当默认值是可变对象(例如列表,字典或大多数类的实例)时,这会有所不同。 例如,以下函数累积在后续调用中传递给它的参数:

下面给出了一个例子

def f(a, L=[]):
L.append(a)
return L print(f(1))
print(f(2))
print(f(3))

打印出来的结果是

[1]
[1, 2]
[1, 2, 3]

这是因为, 作为默认参数, python在启动时就会将变量 L 建立, 我们在函数 f 内对 L 处理就会导致后来调用的 L 已经是修改过的 L 了, 我们可以通过打印 L 的内存地址来验证

def f(a, L=[]):
print(id(L))
L.append(a)
print(id(L))
return L print(f(1))
print(f(2))
print(f(3))

结果是

4513289600
4513289600
[1]
4513289600
4513289600
[1, 2]
4513289600
4513289600
[1, 2, 3]

当然, python的文档中也给出了一个推荐的方法

If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:

def f(a, L=None):
if L is None:
L = []
L.append(a)
return L

即: 将 L 默认为 None, 当该参数未传时, 将 L 设置为空列表, 在Python启动时 L 会设置为 None, 而当我们调用而不传参数 L 时, 在函数 f 内部重新给 L 赋值, 此时 L 为函数 f 内的一个私有变量, 其不会影响到参数 L 本身, 同样的我们可以通过打印内存地址来验证

def f(a, L=None):
print(id(L))
if L is None:
L = []
print(id(L))
L.append(a)
return L print(f(1))
print(f(2))
print(f(3))

输出

4467395776
4469232960
[1]
4467395776
4469232960
[2]
4467395776
4469232960
[3]

当然我们也可以在不更改函数 f 的情况下, 在每次调用 f 的时候都传输参数 L, 如果想让他为一个空列表那就传一个空列表同样能解决问题, 因为你每次指定了值, 便会在传入时修改 L 的值

def f(a, L=[]):
print(id(L))
L.append(a)
print(id(L))
return L print(f(1, []))
print(f(2, []))
print(f(3, []))

输出

4474168192
4474168192
[1]
4474168192
4474168192
[2]
4474168192
4474168192
[3]

python的默认参数的一个坑的更多相关文章

  1. 在python函数中默认参数的一些坑

    一.默认参数 python为了简化函数的调用,提供了默认参数机制: 这样在调用pow函数时,就可以省略最后一个参数不写: 在定义有默认参数的函数时,需要注意以下: 必选参数必须在前面,默认参数在后: ...

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

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

  3. python函数默认参数坑

    def add(a=3,b): print a,b add(4) 这样写的话,运行的话就会报错:SyntaxError: non-default argument follows default ar ...

  4. python函数参数中带有默认参数list的坑

    在python中函数参数中如果带有默认参数list遇到问题 先看一段代码 def f(x,l=[]): for i in range(x): l.append(i*i) print(l) print( ...

  5. 使用可变对象作为python函数默认参数引发的问题

    写python的都知道,python函数或者方法可以使用默认参数,比如 1 def foo(arg=None): 2 print(arg) 3 4 foo() 5 6 foo("hello ...

  6. python函数默认参数陷阱

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

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

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

  8. 关于Inception默认配置的一个坑

    本文地址:https://www.cnblogs.com/ajiangg/p/9850902.html 约半年前上线了去哪儿的开源审核工具Inception(最近发现已经闭源了.....)以及基于In ...

  9. python函数默认参数为可变对象的理解

    1.代码在执行的过程中,遇到函数定义,初始化函数生成存储函数名,默认参数初识值,函数地址的函数对象. 2.代码执行不在初始化函数,而是直接执行函数体. 代码实例 这要从函数的特性说起,在 Python ...

随机推荐

  1. Linux下安装视频转换工具ffmpeg

    ffmpeg下载地址:http://ffmpeg.org/releases/ 1.首先需要安装解码器集合(包含安装ffmpeg用到的所有解码器)下载地址: 链接:https://pan.baidu.c ...

  2. 转:解释lsh

    Locality sensitive hashing - LSH explained The problem of finding duplicate documents in a list may ...

  3. Java设计模式(一)——单例模式

    简介 定义: 确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例. 单例类拥有一个私有构造函数,确保用户无法通过 new 来直接实例化它.类中包含一个静态私有成员变量与静态公有的工厂方法, ...

  4. 八、git学习之——忽略特殊文件、配置别名、搭建git服务器

    原文来自 一.忽略特殊文件 有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files . ...

  5. Angular:惰性加载的模块

    ①通过ng new angular-module创建一个全新的angular应用,默认不选路由 ②通过一下命令分别创建2个模块和1个组件 ng g m hx1 ng g c hx1 ng g m hx ...

  6. mysql数据库设置超时断开连接

    mysql数据库长时间未操作自动断开连接由参数:interactive_timeout和wait_timeout控制,默认都是8小时(28800分钟) mysql> show variables ...

  7. Git中一个由readme.md文件引起的问题

    githup中建立远程仓库时,勾选了创建readme文件,本地仓库无法push,解决方法: https://blog.csdn.net/ashencode/article/details/816249 ...

  8. vue第三单元(webpack的应用-能根据具体的需求构建对应的开发环境)

    第三单元(webpack的应用-能根据具体的需求构建对应的开发环境) #课程目标 理解什么是单页面应用. 掌握单页面和多页面的差异. 了解单页面的实现原理. 掌握模块化的方式实现webpack配置,区 ...

  9. js下 Day04、DOM操作--自定义属性

    语法: 元素.getAttribute('自定义属性名') 功能:获取自定义属性 语法: 元素.setAttribute('自定义属性名','值') 功能:设置自定义属性 语法: 元素.removeA ...

  10. 近期一些使用MATLAB常用的代码

    背景 最近处理行为学数据和fMRI数据,主要使用MATLAB.有一些常用的代码被自己重复使用,所以在此记录,以便于随时调取使用. 1.PVT原生mat文件→txt文件 遇到在处理一些被试的PVT数据时 ...