python可变参数的特点_有趣的 Python 特性 3 | 当心「默认可变参数」这个大猪蹄子...

本文字数:1575 字

阅读本文大概需要:4 分钟

写在之前

Python 提供了很多让使用者觉得舒服至极的功能特性,但是随着不断的深入学习和使用 Python,我发现其中存在着许多玄学的输出与之前预想的结果大相径庭,这个对于初学者来说难以理解,但是在理解它们以后又会觉得是这么的有意思,所以我准备了这个「有趣的 Python 特性」系列,写一些我碰到或看到的一些你所不知道的「奇葩」,这里面会涉及到在 Python2 和 Python3 中的异同,希望大家能从学习的过程中体会到真正的乐趣。

当心默认可变参数

首先我们先来看一个例子:

deftest_func(default_arg=[]): default_arg.append('rocky0429')return default_arg

我们都知道如果调用上述函数 1 次以后所出现的结果:

>>> test_func()['rocky0429']

那么如果调用 2 次,3 次呢?你可以先自己思考一下再继续看下面的结果:

>>> test_func()['rocky0429', 'rocky0429']>>> test_func()['rocky0429', 'rocky0429', 'rocky0429']

咦?明明我们的函数里明明对默认的可变参数赋值了,为什么第 1 次调用是初始化的状态,第 2 次,第 3 次出现的结果就不是我们想要的了呢?先别急,我们再继续看下面的调用:

>>> test_func([])['rocky0429']>>> test_func()['rocky0429', 'rocky0429', 'rocky0429', 'rocky0429']

是不是更懵了?

其实出现这样的结果是因为 Python 中函数的默认可变参数并不是每次调用该函数时都会初始化。相反,它们会使用最近分配的值作为默认值。在上述的 test_func([]) 的结果不同是因为,当我们将明确的 [] 作为参数传递给 test_func() 的时候,就不会使用 test_func 的默认值,所以函数返回的是我们期望的值。

在自定义函数的特殊属性中,有个「 __defaults__」 会以元组的形式返回函数的默认参数。下面我们就用「 __defaults__」来演示一下,以便让大家有个更直观的感觉:

>>> test_func.__defaults__#还未调用([],)>>> test_func() # 第 1 次['rocky0429']>>> test_func.__defaults__# 第 2 次的默认值(['rocky0429'],)>>> test_func() # 第 2 次['rocky0429', 'rocky0429']>>> test_func.__defaults__# 第 2 次的默认值(['rocky0429', 'rocky0429'],)>>> test_func([]) # 输入确定的 []['rocky0429']>>> test_func.__defaults__# 此时的默认值(['rocky0429', 'rocky0429'],)

那么上面那种情况该如何避免呢?毕竟我们还是希望在每次调用函数的时候都是初始化的状态的?这个也很简单,就是将 None 指定为参数的默认值,然后检查是否有值传给对应的参数。所以对于文章开始的那个例子,我们可以改成如下的形式:

deftest_func(default_arg=None):ifnot default_arg: default_arg = [] default_arg.append('rocky0429')return default_arg

以上,完美解决。

●有趣的 Python 特性 2 | 一个你绝对猜不到的结果。

●有趣的 Python 特性 1 | 是谁吃掉了我的外部变量?

●有趣的 Python 特性 0 | 同样都是捕获异常,为啥要不一样呐?

●扔掉压缩工具,让我们用 Python 管理压缩包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值