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
答案 0 :(得分:7)
列表推导实际上是在一个单独的范围内运行的(参见例如Why is one class variable not defined in list comprehension but another is?),因此没有参数的super
的隐式形式在列表推导中不起作用。
您有两种选择,假设您不想回到标准的for
循环:
super
,传递类和实例参数:super(child, self).foo(i)
;或foo
继承parent
时,只需在实例上调用它:self.foo(i)
。