前言

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. Redis Sentinel-深入浅出原理和实战

    本篇博客会简单的介绍Redis的Sentinel相关的原理,同时也会在最后的文章给出硬核的实战教程,让你在了解原理之后,能够实际上手的体验整个过程. 之前的文章聊到了Redis的主从复制,聊到了其相关 ...

  2. 没有它你的DevOps是玩不转的,你信不?

    摘要:架构的选择对于DevOps的实践是至关重要的,从某种程度上来说,架构就是DevOps这场战役的粮草,它是支撑着DevOps成功落地的重要前提. 善用兵者,役不再籍,粮不三载.取用于国,因粮于敌, ...

  3. AcWing 311 .月之谜

    大型补档补了一年 题目链接 考虑枚举月之数的数列和,然后展开dp预处理 设当前模数为 \(P\) \(f[i][j][k]\) 表示一共有 i 位数字,数位和为 j,数值和 % P 的值为 K \(f ...

  4. Python使用requests发送请求

    Python使用第三方包requests发送请求,实现接口自动化 发送请求分三步: 1.组装请求:包括请求地址.请求头header.cookies.请求数据等 2.发送请求,获取响应:支持get.po ...

  5. 初入Nginx--配置篇

    Nginx的主配置文件为/path/to/nginx/nginx.conf.Nginx.conf的配置文件结构主要由以下几个部分组成: ..... events{ .... } http{ .... ...

  6. thinkphp thinkphp6 安装JWT

    第一步:composer安装   composer require firebase/php-jwt 下图是执行成功 cd 进入项目目录的vendor 找到firebase 看到下面有一个php-jw ...

  7. CSS3全览_文本+视觉+盒子+背景颜色

    CSS全览_文本+视觉+盒子+背景颜色 目录 CSS全览_文本+视觉+盒子+背景颜色 1. 文本属性 2. 视觉格式化基础 3. 内边距, 边框, 轮廓和外边距 4. 颜色, 背景和渐变 作者: ht ...

  8. ES6中的Promise和Generator详解

    目录 简介 Promise 什么是Promise Promise的特点 Promise的优点 Promise的缺点 Promise的用法 Promise的执行顺序 Promise.prototype. ...

  9. 抢先看:笔者亲历的2020年中国.NET开发者大会活动纪实

    2020年中国.NET开发者大会活动纪实 1 2020年12月19日的苏州工业园区,天公作美,阳光明媚,气象迷人,正是一个搞事的好日子.在这里,数百名中国.NET开发者们汇聚一堂,怀揣着激情和梦想,一 ...

  10. 从零到一快速搭建个人博客网站(域名自动跳转www,二级域名使用)(二)

    前言 本篇文章是对上篇文章从零到一快速搭建个人博客网站(域名备案 + https免费证书)(一)的完善,比如域名自动跳转www.二级域名使用等. 域名自动跳转www 这里对上篇域名访问进行优化,首先支 ...