python函数把可变数据类型当默认参数值的问题

Python默认参数陷阱
本文深入探讨了Python中使用可变数据类型作为默认参数值时的常见错误,解释了为何这会导致函数行为不符合预期,并提供了两种解决方案。

说明:默认参数值在函数被定义时已经计算出来,而不是在程序运行时。Python 程

序员经常犯的一个错误是把可变的数据类型(例如列表或者字典)当作默认参数值

(一)出现的问题

在下面的例子中,函数 buggy() 在每次调用时,添加参数 arg 到一个空的列表 result ,然
后打印输出一个单值列表。但是存在一个问题:只有在第一次调用时列表是空的,第二次
调用时就会存在之前调用的返回值

def buggy(arg, result=[]):
    result.append(arg)
    print(result)

print('--------1--------')
buggy('a')
print('--------2--------')
buggy('b')  # 期望得到 ['b']

执行结果:

--------1--------
['a']
--------2--------
['a', 'b']

(二)解释并测试

1.默认参数值在函数被定义时已经计算出来,而不是在程序运行时

2.只要函数调用时没有传递新的列表来覆盖默认参数列表,函数就会使用定义时的那个列表,并且操作依次叠加

3.上面两次调用中,都没有传递新的列表,程序会调用定义函数时保存的默认参数,并在上一次的基础上进行操作叠加,即:列表在append的时候会在 result原来的基础上append追加值,所以会产生以上结果.

我们通过打印列表的ID进行辨识来看看:

def buggy(arg, result=[]):
    print(id(result))
    result.append(arg)
    print(result)

print('--------1--------')
buggy('a')
print('--------2--------')
buggy('b')  # expect ['b']

结果:

--------1--------
12205768
['a']
--------2--------
12205768
['a', 'b']

我们会发现ID值是相同的;

说明两次执行时使用的都是开始定义函数时的默认参数 ,进行了操作叠加

4.下面我们传递新的列表看看:

def buggy(arg, result=[]):
    print(id(result))
    result.append(arg)
    print(result)

print('--------1--------')
buggy('a')
print('--------2--------')
buggy('b', [])  # 传递了新的列表

结果:

--------1--------
18497224
['a']
--------2--------
18504648
['b']

发现,列表id不同,并且得到了我们期望的值

(三)解决方法

方法1

# 如果写成下面的样子就会解决刚才的问题:

def works(arg):
    result = []
    result.append(arg)
    print(result)

works('a')
works('b')

结果:

['a']
['b']

方法2:

# 这样的修改也为了表明是第一次调用跳过一些操作:

def nonbuggy(arg, result=None):
    if result is None:
        result = []
    result.append(arg)
    print(result)

nonbuggy('a')
nonbuggy('b')

结果:

['a']
['b']
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值