返回顶部
首页 > 资讯 > 后端开发 > Python >python函数的默认参数请勿定义可变类型详解
  • 535
分享到

python函数的默认参数请勿定义可变类型详解

2024-04-02 19:04:59 535人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录函数的默认参数请勿定义可变类型可变类型和不可变类型定义可变类型会有什么问题?导致的原因解决方法关于可变类型作为默认参数时的注意点测试:将可变类型列表换为字典测试:来个不可变类型字

函数的默认参数请勿定义可变类型

经常会看到这样一句代码警告:

Default argument value is mutable

意思是告诉我们函数的定义中,使用可变类型做默认参数。

那为什么会有这个警告呢?

可变类型和不可变类型

  • 可变类型(mutable):列表,字典
  • 不可变类型(unmutable):数字,字符串,元组

定义可变类型会有什么问题?

def fun(a=[]):
    a.append(1)
    print(a)
if __name__ == "__main__":
    fun()
    fun()
>>> [1]
    [1, 1]

可以发现,默认参数定义可变类型之后,在第二次乃至更多次地调用同一个函数时,默认参数仿佛失去了效果。

此时,在需要重复调用同一个函数的场景中,就非常容易导致问题,并且该问题不易察觉。在debug的时候就会表现成明明没有参数传进来,但是函数参数会有值,并且执行了不应该执行的操作。

导致的原因

我的理解:

我们定义的函数本身是一个function的实例化对象,每当我们进行函数的定义时,就是创建了一个function的实例化对象,而默认参数就是其属性。

在没有传入参数,以默认参数形式调用,并且改变了函数对象的属性值时,改变的属性值被保存下来,当第二次调用同一个对象时,属性值已经发生了改变。

type(fun)
>>> function

解决方法

def fun(a=None):
    if a is None:
    a = []
    a.append(1)
    print(a)
if __name__ == "__main__":
    fun()
    fun()
>>> [1]
    [1]

关于可变类型作为默认参数时的注意点

请先看代码,看看代码的输出是否和你想的一样。

def e(v,l=[]):
    l.append(v)
    return l
l1=e(10)
l2=e(123,[])
l3=e("a")
print(l1,l2,l3)
# 输出: ([10, 'a'], [123], [10, 'a'])

关于上述代码,标准解释是:带有默认参数的表达式在函数被定义的时候被计算,不是在调用的时候计算。

我觉得通俗的解释是:当不传默认值的时候,无论调用多少次该函数,在函数体内部使用的一直都是那个默认的“l”,而这个默认的“l”又是可变类型,所以,它的改变会影响所有指向它的变量,也就是l1和l3。

为了使以上两点的观点更加站的住脚,我进行以下几个测试。

测试:将可变类型列表换为字典

def e(k,v,d={}):
    d[k]=v
    return d
d1=e(10,10)
d2=e(123,123,{})
d3=e("a","a")
print(d1,d2,d3)
# 输出:({'a': 'a', 10: 10}, {123: 123}, {'a': 'a', 10: 10})

测试:来个不可变类型字符串

def e(v,s=""):
    s = s+v
    return s
s1=e("我")
s2=e("a","")
s3=e("是")
print(s1,s2,s3)
# 输出: 我 a 是

其实以上类型都已经说明问题了,但是写个文章不容易,我决定用元祖包列表,看看修改这个列表中的数据会怎样。

实际上是不用测试的,最终打印出来的数据一定是类似**“可变类型时的操作”**时的输出的。

为什么?因为我没有修改元祖本身,修改的是其可变类型列表啊。

不能扯远了,不然扯到深拷贝,浅拷贝了。

测试:元祖包个列表来

def e(v,t=([],)):  # 传递有元素的元祖的时候要记得带逗号哦。
    
    t[0].append(v)
    # t = t[0].append(v)     要知道t[0].append(v)是没有返回值的,t会指向None,如果这样返回,外部打印的全部为None,所以不可以这样返回。
    # 而且 如果你想 t[0]= t[0].append(v) 也是不行的,为啥?你在ipython中输入 dir(())你就知道了。
    # 好吧,其实是因为元祖是可读不可写的。它能切片、遍历就已经很不错了。。。。。
    return t
t1=e("我")
t2=e("a",([],))
t3=e("是")
print(t1,"\n",t2,"\n",t3)
# 输出:
# (['我', '是'],) 
# (['a'],) 
# (['我', '是'],)

小结一下

家里停电了,所以我来到了网吧,这篇文章是在网吧写的,用的是python3的在线编辑器,有的地方编码(比如命名-。-)或者表述的不好请多多见谅。

关于集合,我就不做测试了,集合一般用于去重和关系运算,它是无序,不重复,可变类型。 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: python函数的默认参数请勿定义可变类型详解

本文链接: https://lsjlt.com/news/138887.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • python函数的默认参数请勿定义可变类型详解
    目录函数的默认参数请勿定义可变类型可变类型和不可变类型定义可变类型会有什么问题?导致的原因解决方法关于可变类型作为默认参数时的注意点测试:将可变类型列表换为字典测试:来个不可变类型字...
    99+
    2024-04-02
  • python函数的默认参数为什么不可以定义可变类型
    这篇文章主要介绍“python函数的默认参数为什么不可以定义可变类型”,在日常操作中,相信很多人在python函数的默认参数为什么不可以定义可变类型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python函...
    99+
    2023-06-29
  • C++ 函数的默认参数和可变参数详解
    c++++ 默认参数允许为函数参数设置默认值,而在可变参数中,可以为函数提供任意数量的参数。具体而言:默认参数:允许在函数声明时为参数指定默认值,在调用时如果没有提供值则使用默认值。可变...
    99+
    2024-04-19
    编程 c++
  • Python中的函数参数(位置参数、默认参数、可变参数)
    目录一、位置参数二、默认参数三、可变参数四、关键字参数五、命名关键字参数六、各种参数之间的组合函数的参数:Python中函数定义非常简单,由于函数参数的存在,使函数变得非常灵活应用广...
    99+
    2024-04-02
  • Python---限定函数参数的类型及默
    python作为一门动态语言,在使用变量之前是不需要进行定义,而是通过动态绑定的方法将变量绑定为某种类型。这样做为我们使用变量时提供了方便,但有时也给我们使用变量时造成了一定的困扰,例如在使用变量时不知道变量的类型,使用函数时不知...
    99+
    2023-01-31
    函数 参数 类型
  • 如何为 PHP 函数指定参数的默认类型
    为 php 函数指定参数的默认类型可以提高代码的可读性、加强类型检查和提供自动类型转换。这适用于 php 7.0 及更高版本,语法为:function funcname(type $pa...
    99+
    2024-04-19
    php 函数参数
  • Python进阶-函数默认参数(详解)
    一、默认参数 python为了简化函数的调用,提供了默认参数机制: def pow(x, n = 2): r = 1 while n > 0: r *= x n -= 1...
    99+
    2022-06-04
    进阶 详解 函数
  • python-自定义函数(定义调用、默认参数、返回值)
    python-自定义函数 文章目录 python-自定义函数初识函数函数的定义与调用函数的定义:参数列表:函数体:函数调用 默认参数定义默认参数:默认参数的使用:默认参数的位置:默认参数...
    99+
    2023-09-10
    python 开发语言 numpy
  • C++ 函数默认参数和可变参数在泛型编程中的作用
    c++++ 中的默认参数和可变参数在泛型编程中发挥着至关重要的作用:默认参数允许函数在调用时指定可选参数,便于处理不同类型和默认值的元素。可变参数允许函数接受任意数量的参数,便于处理可变...
    99+
    2024-04-22
    c++ 泛型编程 键值对
  • C++ 函数默认参数与可变参数的优缺点比较
    c++++ 函数中默认参数的优点包括简化调用、增强可读性、避免错误。缺点是限制灵活性、命名限制。可变参数的优点包括无限灵活性、动态绑定。缺点包括复杂性更高、隐式类型转换、调试困难。 C...
    99+
    2024-04-21
    函数 c++ 隐式类型转换
  • PHP 函数参数类型的默认值是什么?
    php 函数中的参数可以具有默认值,可在函数声明中指定,在省略时使用。语法:function function_name(type $parameter1 = default_value...
    99+
    2024-04-10
    php 参数默认值
  • Python中的默认参数详解
    文章的主题 不要使用可变对象作为函数的默认参数例如 list,dict,因为def是一个可执行语句,只有def执行的时候才会计算默认默认参数的值,所以使用默认参数会造成函数执行的时候一直在使用同一个对象,引起bug。 基本原理 在 ...
    99+
    2023-01-31
    详解 参数 Python
  • Python中自定义函方法与参数具有默认值的函数
    目录一、Python中自定义函数的方法1自定义函数的语法2自定义函数的实现3自定义函数的调用二、Python中参数具有默认值的函数1参数是常量默认值的函数2参数是常量默认值的函数一、...
    99+
    2024-04-02
  • Python中函数的参数类型详解
    目录1、Python的函数参数的类型2、Python的必传参数3、关键字参数4、默认参数5、不定长参数1、Python的函数参数的类型 必传参数:调用函数时必须传入的参数,函数定义时...
    99+
    2024-04-02
  • 函数中输入参数的可变类型
    php小编苹果为您介绍函数中输入参数的可变类型。在php中,函数的参数类型可以是固定的,也可以是可变的。可变类型参数,指的是函数可以接受不同类型的参数作为输入,这在处理不同场景下的数据...
    99+
    2024-02-09
  • 探究 C++ 函数默认参数和可变参数的底层实现
    默认参数: 在函数定义中指定参数默认值,使用常数预定义;可变参数: 使用省略号表示,编译为指向数组的指针,打包传入参数,遍历数组访问参数。 探究 C++ 函数默认参数和可变参数的底层实...
    99+
    2024-04-22
    c++ 可变参数 函数默认参数 python
  • C++ 函数默认参数和可变参数的内存管理剖析
    默认参数和可变参数的内存管理:默认参数:在函数栈帧中分配内存,大小为其类型的字节数。可变参数:在堆栈帧的尾部分配内存,大小由可变参数数量决定:sizeof(void ) (传入参数数量...
    99+
    2024-04-19
    函数 c++
  • C++ 函数默认参数和可变参数对程序性能的影响
    默认参数在编译时展开,不影响运行时性能;可变参数会产生运行时开销,应避免密集使用。 C++ 函数默认参数和可变参数对程序性能的影响 默认参数 默认参数允许函数在不传递实际参数的情况下指...
    99+
    2024-04-22
    程序性能 函数参数 c++
  • 如何优化 C++ 函数中默认参数和可变参数的使用
    优化 c++++ 默认和可变参数函数:默认参数:允许函数使用默认值,减少冗余。将默认参数放在最后以提高可读性。使用 constexpr 默认参数以减少开销。使用结构化绑定以提高复杂默认参...
    99+
    2024-04-20
    默认参数 可变参数 c++ 函数 c++
  • Python中如何自定义函方法与参数具有默认值的函数
    这篇“Python中如何自定义函方法与参数具有默认值的函数”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中如何自...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作