超类的实例变量的值在子类的实例之间持久存在

ale*_*ras 4 python oop

我不确定这是否是我对Python中OOP工作方式的基本误解,但我看到了一些非常奇怪的行为.这是一段代码片段:

class Foo(object):
    def __init__(self, l = []):
        print "Foo1:", l
        self.mylist = l
        print "Foo2:", self.mylist

class Bar(Foo):
    def __init__(self, label=None):

        self.label = label
        super(Bar, self).__init__()
        print "Bar:", self.mylist



bar1 = Bar()
bar1.mylist.append(4)

bar2 = Bar()
print "bar2's list:", bar2.mylist
Run Code Online (Sandbox Code Playgroud)

我希望在bar2构造时,它的mylist实例变量将被设置为空列表.但是,当我在Python 2.6.6中运行此程序时,我得到以下输出:

Foo1: []
Foo2: []
Bar: []
Foo1: [4]
Foo2: [4]
Bar: [4]
bar2's list: [4]
Run Code Online (Sandbox Code Playgroud)

看起来Foo的mylist实例变量被保存在Bar类的多个实例中,但我不知道为什么会这样.你们可以给我的任何帮助将不胜感激.

Mic*_*yan 6

问题是默认参数在模块初始化时绑定,而不是在函数调用时绑定,因此只有一个默认列表作为该函数的所有调用的默认值共享.

你真正想做的是:

def __init__(self, l=None):
    if l is None:
        l = []
    self.mylist = l
Run Code Online (Sandbox Code Playgroud)


Tah*_*gir 5

查阅有关默认参数值的 Python 教程\n它说:

\n\n
\n

重要警告:默认值仅计算一次。当默认值是可变对象(例如列表、字典或大多数类的实例)时,这会产生影响。

\n
\n\n

或者例如,以下函数会累积在后续调用中传递给它的参数:

\n\n
def f(a, L=[]):\n    L.append(a)\n    return L\n\nprint f(1)\nprint f(2)\nprint f(3)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将打印

\n\n
[1]\n[1, 2]\n[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)\n\n

如果您不希望在后续调用之间共享默认值,您可以像这样编写函数:

\n\n
def f(a, L=None):\n    if L is None:\n        L = []\n    L.append(a)\n    return L
Run Code Online (Sandbox Code Playgroud)\n