不能在子初始化程序中的列表理解中调用父方法,但是显式循环工作

时间:2015-07-01 13:32:21

标签: python python-3.x inheritance

child类继承自parent类。在child的构造函数内部,我通过重复调用list中定义的成员函数xs来初始化foo() - 类型成员变量parent。事实证明,如果我通过显式循环并附加xs返回的每个值来初始化foo(),那么一切正常。

但是,如果我尝试在列表理解中做同样的事情,我会收到一个奇怪的错误。为什么会出现此错误?在这种情况下,列表理解与显式循环之间有什么区别?

有效的代码的MWE:

class parent(object):
    def __init__(self):
        self.x = 5

    def foo(self, a):
        return self.x


class child(parent):
    def __init__(self):
        super().__init__()

        self.xs = []
        for i in range(9):
            self.xs.append(super().foo(i))    

mychild = child()

child的定义,但列表理解:

class child(parent):
    def __init__(self):
        super().__init__()
        self.xs = [super().foo(i) for i in range(9)]

有问题的错误:

% python test.py
Traceback (most recent call last):
  File "test.py", line 20, in <module>
    mychild = child()
  File "test.py", line 17, in __init__
    self.xs = [super().foo(i) for i in range(9)]
  File "test.py", line 17, in <listcomp>
    self.xs = [super().foo(i) for i in range(9)]
TypeError: super(type, obj): obj must be an instance or subtype of type
zsh: exit 1     python test.py

1 个答案:

答案 0 :(得分:7)

列表推导实际上是在一个单独的范围内运行的(参见例如Why is one class variable not defined in list comprehension but another is?),因此没有参数的super的隐式形式在列表推导中不起作用。

您有两种选择,假设您不想回到标准的for循环:

  1. 使用显式形式的super,传递类和实例参数:super(child, self).foo(i);或
  2. 当您从foo继承parent时,只需在实例上调用它:self.foo(i)