Python中list作为默认参数的陷阱

  在Python中,作为默认参数的一定要是不可变对象,如果是可变对象,就会出现问题,稍不注意,就会调入陷阱,尤其是初学者,比如我(┬_┬)。

  我们来看一个例子。

 1 def add(L=[]):
 2     L.append(1)
 3     return L
 4
 5 L = [1, 2, 3]
 6 newL = add(L)
 7 print(newL)
 8 newL = add(newL)
 9 print(newL)
10
11 testL = add()
12 print(testL)
13 testL = add()
14 print(testL)
15 testL = add()
16 print(testL)

  运行结果如图:

  

  在正常传入参数的时候,好像没什么大问题。但是当我们使用默认参数的时候,问题出现了。

  运行结果没有按我们的预期出现。原因何在?

  当我们调用函数时,如果有传递参数,则使用传递的参数,如果没有传递参数,就使用默认参数。而使用默认参数的时候,使用的是同一个,也就是保存的上一个默认参数值。我们可以通过打印id来验证一下。

  

  因此,默认参数一定要是不可变对象,如果是可变对象的话,就会出现上述情况。

  那么如何解决呢?

  我们可以让L先指向None这个不可变变量,然后增加一个判断,让默认参数重新归位即可。

 1 def add(L=None):
 2     if(L == None):
 3         L = []
 4     L.append(1)
 5     return L
 6
 7 L = [1, 2, 3]
 8 newL = add(L)
 9 print(newL)
10 newL = add(newL)
11 print(newL)
12
13 testL = add()
14 print(testL)
15 testL = add()
16 print(testL)
17 testL = add()
18 print(testL)

  

  这样子,我们就解决了这个陷阱,那么下次就不应该再掉进去了,你说是不是?

  牢记:默认参数要使用不可变对象!!!

  不可变(immutable):int、string、float、number、tuple

  可变(mutable):dictionary、list、set

原文地址:https://www.cnblogs.com/Bil369/p/9400548.html

时间: 2024-08-24 22:18:11

Python中list作为默认参数的陷阱的相关文章

在python中,用默认参数(list,set,dict...)时要小心

在我们平时写需求的时候,如果没有了解到以下知识点,可能会出现这样的问题,掉进坑里面,甚至很难找到问题的根源.下面我们来看看使用可变默认参数(Mutable default arguments)时会出现什么诡异的情况. 你可能写了以下函数,它有一个默认参数是一个list: def append_to(element, to=[]): to.append(element) return to 然后调用该函数: my_list = append_to(12) print(my_list) my_oth

Python(55)_默认参数的陷阱

#-*-coding:utf-8-*- ''' 函数复习 ''' def f(): return 'bowen' print(2+3) # 事实上python中会调用内部的函数,相当于add() print(f()) def wahaha(*args): print(args) wahaha(1,2,3) l = [1,2,3] wahaha(*l) ''' 默认参数的陷阱 如果默认参数的值是一个可变数据类型,那么每一次调用的时候,不传值就公用这个数据类型的资源 简单的说,就是不传值的情况下,始

[Python] partial改变方法默认参数

Python 标准库中 functools库中有很多对方法很有有操作的封装,partial Objects就是其中之一,他是对方法参数默认值的修改. 下面就看下简单的应用测试. #!/usr/bin/env python # -*- coding: utf-8 -*- #python2.7x #partial.py #authror: orangleliu ''' functools 中Partial可以用来改变一个方法默认参数 1 改变原有默认值参数的默认值 2 给原来没有默认值的参数增加默认

默认参数的陷阱

默认参数的陷阱 : 默认参数实际上只有一个值 如果是可变数据类型,无论这个函数被调用多少次, 共用这个默认参数a = []b = []a.append(1)print(a,b) a = []b = aa.append(1)print(a,b) 变量是变量,值是值变量的名字和有多少个值 没有对应关系我们在看修改的时候 : 要看修改的是哪一个具体的值而不是变量 l = [] # 在定义函数之前定义了一个[]def func(): l.append(1)func()func()func()func()

python中from module import * 的一个陷阱

from module import *把module中的成员全部导到了当前的global namespace,访问起来就比较方便了.当然,python style一般不建议这么做,因为可能引起name conflict. 但还有另外一个问题 - 你以为你修改了某个变量,其实,被from module import *后的那个并没有被更新,非常危险,因为程序有可能还可以正常运行, 只不过结果错了,到了production才被发现就比较惨了. 举个例子: 你定义了一些变量在base模块中: # r

默认参数的陷阱自我心得

默认参数的陷阱 : 默认参数实际上只有一个值 代码1 def func(l = 1): l += 1 print(l) func() func() func() 代码2 lst = [] def func(a,l = lst): l.append(a) print(l)func(1) # [1] func(2,[]) # [2] func(3) # [1,3]变量是变量,值是值 变量的名字和有多少个值没有对应关系 我们在看修改的时候:要看修改的是哪一个对应的值而不是变量 def func(l =

python中定义函数和参数的传递问题

作者:達聞西链接:https://zhuanlan.zhihu.com/p/24162430来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 5.2.4 函数.生成器和类 还是从几个例子看起: def say_hello(): print('Hello!') def greetings(x='Good morning!'): print(x) say_hello() # Hello! greetings() # Good morning! greetings("Wh

[python 函数学习篇]默认参数

python函数: 默认参数: retries=4 这种形式 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while True: ok = raw_input(prompt) if ok in ('y', 'ye', 'yes'): return True if ok in ('n', 'no', 'nop', 'nope'): return False retries = retries - 1 if retri

python的位置参数、默认参数、关键字参数、可变参数区别

一.位置参数 调用函数时根据函数定义的参数位置来传递参数. #!/usr/bin/env python # coding=utf-8 def print_hello(name, sex): sex_dict = {1: u'先生', 2: u'女士'} print 'hello %s %s, welcome to python world!' %(name, sex_dict.get(sex, u'先生')) # 两个参数的顺序必须一一对应,且少一个参数都不可以 # print_hello('t