python类的初始化与默认参数的陷阱
本文将深入探讨python中类的初始化机制,并解释为什么在定义类时使用可变对象作为默认参数会导致意料之外的行为,以及如何避免此类问题。
我们以一个名为list的类为例,观察其初始化方法__init__的不同实现方式对结果的影响。
首先,让我们看第一个例子:
class list(object): def __init__(self): self.list=[]list1=list()list1.list.append('12')list2=list()print(list2.list)
这段代码的输出结果是[]。这是因为在__init__方法中,每次创建list实例时,都会创建一个新的空列表赋给self.list。因此,list1和list2拥有各自独立的列表。
立即学习“Python免费学习笔记(深入)”;
然而,如果我们修改__init__方法,使用一个列表作为默认参数:
class list(object): def __init__(self,list=[]): self.list=list self.str=strlist1=list()list1.list.append('12')list2=list()print(list2.list)
这段代码的输出结果却变成了[’12’]。这与我们直觉上的结果相悖。
问题的关键在于python默认参数的赋值时机。默认参数的值是在定义函数时就确定的,而不是在每次调用函数时确定的。这意味着在上面的第二个例子中,list=[] 只执行一次,在list类定义的时候就创建了一个空列表,之后每次调用__init__方法时,self.list 都指向这个同一个列表。因此,list1修改了这个列表后,list2 使用的也是同一个列表,所以输出了[’12’]。
为了更好地理解这个问题,我们可以将代码等价地改写成:
defaultlist = []class list(object): def __init__(self, list=none): if list: self.list = list else: self.list = defaultlistlist1 = list()list1.list.append('12')list2 = list()print(list2.list)
这段代码更清晰地展现了默认参数的陷阱:list1 和 list2 的 self.list 都指向同一个 defaultlist。
为了避免这种问题,最佳实践是使用none作为默认参数,并在__init__方法内部进行条件赋值:
class List(object): def __init__(self, list=None): self.list = list if list != None else []list1 = List()list1.list.append('12')list2 = List()print(list2.list)
这样,每次创建list实例时,都会创建一个新的空列表,避免了共享同一个列表的风险,从而保证了各个实例的独立性。
以上就是Python类初始化:为什么默认参数是可变对象时会出错?的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1357690.html
微信扫一扫
支付宝扫一扫