令人困惑的python:在类init中空列表作为可选的kwarg



我理解python中为什么会发生以下情况,但这似乎有点违反直觉。谁能解释一下为什么python应该这样做?为什么在类G的第二次实例化时没有再次创建空列表?

class G:
def __init__(self, members=[]):
self.members = members
def append(self, x):
self.members.append(x)

a = G()
a.append(1)
a.append(2)
print(a.members)  # prints: [1, 2]
b = G()
print(b.members)  # prints: [1, 2]    <-------- why????

编辑:正如评论中提到的,这个问题已经在这里解决了。

在定义时计算默认值。因此,只创建一个列表,并且默认值始终指向它。

print(id(a.members))  
print(id(b.members))  
print(a.members is b.members)

输出:

140226208543200
140226208543200
True

这与类无关。这也适用于任何计划函数。

def f(y,x=[]):
x.append(y)
return x
print(f(5)) #returns [5]
print(f(7)) #returns [5,7]

之所以会发生这种情况,是因为当函数编译到内存中时,python创建了一个带有指针的列表,该指针被赋值为默认变量"x"在函数中"f"。当我们执行" x.p end"我们告诉python在内存中添加函数的默认列表。为了避免这种行为,你需要避免操作默认值(谷歌可变和不可变对象)。

def f(y,x=[]):
x = list(x) #copy the default
x.append(y)
return x

最新更新