Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >为什么禁止把函数参数默认值设置为可变对象?

为什么禁止把函数参数默认值设置为可变对象?

作者头像
活用数据
发布于 2022-10-04 12:18:25
发布于 2022-10-04 12:18:25
1.4K00
代码可运行
举报
文章被收录于专栏:数据医生专栏数据医生专栏
运行总次数:0
代码可运行

本文主要是对禁止使用可变对象作为参数默认值的编码规范进行了详细介绍。

今天给大家带来的是一篇编程规范方面的内容。

有时候我们在编写函数时,会需要给一些参数设置默认值,这个时候我们需要牢记一点:禁止使用可变对象作为参数默认值

从一个“反例”开始

我们先编写一个不符合规范的“反例”看看:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 【反例】
def f(a, lst=[]):
    lst.append(a)
    return lst

在上面的反例中,我们就使用了可变对象列表,作为我们的参数默认值。

接下来我们用静态代码检查工具pylint检查一下上面的“反例“:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pylint example.py


# Output
************* Module example
example.py:1:0: C0114: Missing module docstring (missing-module-docstring)
example.py:1:0: W0102: Dangerous default value [] as argument (dangerous-default-value)
example.py:1:0: C0103: Function name "f" doesn't conform to snake_case naming style (invalid-name)
example.py:1:0: C0103: Argument name "a" doesn't conform to snake_case naming style (invalid-name)
example.py:1:0: C0116: Missing function or method docstring (missing-function-docstring)

------------------------------------
Your code has been rated at -6.67/10

这里主要看第二条建议:example.py:1:0: W0102: Dangerous default value [] as argument (dangerous-default-value)

非常明显地提示列表[]是一个危险的默认值,这究竟是为什么呢?

为什么可变对象作为函数默认值很危险?

我们还是使用上面那个简单的“反例”,再传递几个参数,通过结果,就可以明显地看到为什么不建议我们这样做了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 【反例】
def f(a, lst=[]):
    lst.append(a)
    return lst

print(f('1'))  # 期望 -> ['1']
print(f('2'))  # 期望 -> ['2']
print(f('3', []))  # 期望 -> ['3']
print(f('3', ['1', '2']))  # 期望 -> ['1', '2', '3']


# 实际输出
['1']
['1', '2']
['3']
['1', '2', '3']

从结果我们可以看到,第二次调用函数f('2')的结果是跟我们预期不符的,我们本来的期望值是没有传入lst参数,那么应该给我们返回一个['2'],但是实际结果却是['1', '2']

这是因为Python函数的默认值只会创建一次,之后第二次调用的时候就是在原默认值上进行修改,而不是重新创建了一个新的默认值,这也就能够解释得通实际结果为什么是这样的了。

所以说,使用可变对象作为默认值会导致得到超出我们预期的结果,这可能会导致出现一些无法定位的bug。

那么,我们应该怎么做?

我们应该怎么做?

既然我们不能使用可变对象作为参数默认值,那么使用不可变对象作为参数默认值就好了,然后再在代码中对默认值的数据类型进行修改。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 【正例】写法一
def f(a, lst=None):
    if not lst:
        lst = []
    lst.append(a)
    return lst

print(f('1'))  # 期望 -> ['1']
print(f('2'))  # 期望 -> ['2']
print(f('3', []))  # 期望 -> ['3']
print(f('3', ['1', '2']))  # 期望 -> ['1', '2', '3']


# 实际输出
['1']
['2']
['3']
['1', '2', '3']

可以看到,把参数默认值设置为不可变对象的写法就完全符合我们的预期了。

我们还可以简化成下面的写法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 【正例】写法二
def f(a, lst=None):
    lst = lst or []
    lst.append(a)
    return lst

上面两种写法都是等价的,而且用pylint检查也不会再出现那个警告了。

今天关于这个编码规范的介绍就到此结束了,喜欢的朋友们可以点一个关注,后续会输出更多关于Python编码规范的相关内容。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何让 Python 代码更专业?
自己写代码只给自己看,其实怎么写都行。一旦有团队合作,或者要分享自己的代码,就要好好写了,专业的代码可以为自己积累技术影响力。
somenzz
2022/05/24
7910
如何让 Python 代码更专业?
你需要知道的Python代码规范性检查(pylint和flake8)
关于Python代码规范,之前写过一篇相关的文章你熟悉Python的代码规范吗?如何一键实现代码排版,大家可以先看下。
吾非同
2020/10/23
8.4K0
你需要知道的Python代码规范性检查(pylint和flake8)
python代码检查工具pylint-让你的python更规范
遇到一个新的问题,总是离不开3W原则(What,Why,hoW),下面是对python代码静态检测工具pylint的学习:
the5fire
2019/02/28
3.9K0
Python函数签名的参数设计以及=None的重要性
位置参数(Positional Arguments):最常见的参数类型,按照位置传递。
运维开发王义杰
2023/09/19
5540
Python函数签名的参数设计以及=None的重要性
Python 函数中使用默认值参数 — 谈谈可变对象的坑?!
在 python 中定义函数,其参数可以使用多种不同的方式,其中包括 “默认值参数”类型,那么当作默认值的对象有什么限制和要求么?这里搞不好还真有坑! 接下来我们主要从两个角度来谈谈。
用户7886150
2021/01/16
1.6K0
教你一招 | Python: 函数参数魔法
函数参数 在 Python 中,定义函数和调用函数都很简单,但如何定义函数参数和传递函数参数,则涉及到一些套路了。总的来说,Python 的函数参数主要分为以下几种: 必选参数 默认参数 可变参数 关键字参数 必选参数 必选参数可以说是最常见的了,顾名思义,必选参数就是在调用函数的时候要传入数量一致的参数,比如: >>> def add(x, y): # x, y 是必选参数 ... print x + y ... >>> add() # 啥都没传,不行
CDA数据分析师
2018/02/05
7710
盘一盘 Python 系列 1 - 入门篇 (下)
Python 里函数太重要了 (说的好像在别的语言中函数不重要似的)。函数的通用好处就不用多说了吧,重复使用代码,增强代码可读性等等。
用户5753894
2019/07/05
1.3K0
盘一盘 Python 系列 1 - 入门篇 (下)
Python函数参数之全面讲解
Python函数参数 Python函数参数 本文主要介绍Python的函数参数,各种形式的参数。建议动手试试,可以加深理解。 函数参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂的逻辑被封装起来,调用者无需了解。 Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以
1846122963
2018/03/09
1.4K0
动态语言的灵活性是把双刃剑:以 Python 语言为例
新媒体管家 关键时刻,第一时间送达! 本文有些零碎,总题来说,包括两个问题:(1)可变对象(最常见的是list dict)被意外修改的问题,(2)对参数(parameter)的检查问题。这两个问题,本质都是因为动态语言(动态类型语言)的特性造成了,动态语言的好处就不细说了,本文是要讨论因为动态--这种灵活性带来的一些问题。 什么是动态语言(Dynamic Programming language)呢,是相对于静态语言而言,将很多静态语言编译(compilation)时期所做的事情推迟到运行时,在运行时修改代
企鹅号小编
2018/01/10
1.4K0
开源图书《Python完全自学教程》6.3.2两个常用函数
Python 内置函数 zip() 的基本调用形式是 zip(*iterables) ,其参数应为可迭代对象,且用符号 * 表示可以是多个可迭代对象(参阅第7章7.2节),例如:
老齐
2022/05/17
3900
为什么说python里面函数参数的默认值最好不要使用可变类型
之前发布过Python中函数的介绍:Python中函数的介绍 ,今天来做一个小小的补充说明:为什么说python里面函数参数的默认值最好不要使用可变类型
小博测试成长之路
2023/09/01
2240
为什么说python里面函数参数的默认值最好不要使用可变类型
Golang动态可变函数参数 参数默认值
作者:matrix 被围观: 4 次 发布时间:2024-08-17 分类:Golang | 无评论 »
HHTjim 部落格
2024/08/17
1180
我发现了用 Python 编写简洁代码的秘诀!
作为数据科学家,我们常常使用 Jupyter Notebooks 进行数据探索和模型开发。在这个阶段,我们关注的重点是快速验证想法和证明概念。然而,一旦模型准备就绪,就需要将其部署到生产环境中,这时代码质量就显得尤为重要。
数据STUDIO
2024/06/04
2030
我发现了用 Python 编写简洁代码的秘诀!
程序员必知的 Python 陷阱与缺陷列表
我个人对陷阱的定义是这样的:代码看起来可以工作,但不是以你“想当然”的方式。如果一段代码直接出错,抛出了异常,我不认为这是陷阱。比如,Python程序员应该都遇到过的“UnboundLocalError”, 示例:
IT派
2018/07/30
5970
开源图书《Python完全自学教程》7.1.3参数
图7-1-1所示的函数基本格式中,圆括号里面的参数是可选项。如果为空,即没有参数,如前面使用过的函数 laoqi() 那样。如果不为空,如7.1.2节中定义的 fibo_loop() 函数那样,在调用它的时候就要“向函数传对象”——注意带有引号的说法。在 Python 中,“向函数传对象”或者“向函数传值”、“向函数传参数”,这些说法的含义都是一样的,也都是简化了的俗语——不严格,但形象直接。
老齐
2022/07/06
3360
开源图书《Python完全自学教程》7.1.3参数
3大利器推荐,帮你写出规范漂亮的python代码
Python学了好久,但是拿出来review的代码好像总是长的不够俊美,不够工整!因此标准化的代码规范就显得尤为重要。今天就来推荐3个利器,python界广泛认同的代码风格规范PEP8和两个超牛的工具pylint和black,分别用于代码风格规范检测和自动优化。
墨鬓
2020/08/03
1.1K0
Python函数默认值参数的2个坑
在定义函数时,Python支持默认值参数,在定义函数时可以为形参设置默认值。在调用带有默认值参数的函数时,可以不用为设置了默认值的形参进行传值,此时函数将会直接使用函数定义时设置的默认值,当然也可以通过显式赋值来替换其默认值。也就是说,在调用函数时是否为默认值参数传递实参是可选的,具有较大的灵活性。例如: >>> def say( message, times =1 ): print((message+' ') * times) >>> say('hello') hello >>> say('hello'
Python小屋屋主
2018/04/16
1.3K0
Python函数参数和注解是什么
⑥字典前加上**,其所有元素作为单个参数传入,同名键会绑定到对应具名参数上,余下的被**args捕获。
dongfanger
2021/04/13
6340
小心此坑:Python 函数参数的默认值是可变对象
看到了有给 Python 函数参数的默认值传递可变对象,以此来加快斐波那契函数的递归速度,代码如下:
somenzz
2023/01/03
1.1K0
小心此坑:Python 函数参数的默认值是可变对象
【Python入门第十四讲】函数(Function)篇
Python 函数是返回特定任务的语句块。它将一些常见或重复完成的任务放在一起并创建一个函数,这样我们就可以执行函数调用以一遍又一遍地重用其中包含的代码,而不是为不同的输入一次又一次地编写相同的代码。
不惑
2024/02/09
5370
【Python入门第十四讲】函数(Function)篇
推荐阅读
相关推荐
如何让 Python 代码更专业?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验