在Python3中,可以使用super()
代替super(MyClass, self)
,但这只适用于在类内部定义的方法。如Michele Simionato's article中所述,以下示例不起作用:
def __init__(self):
print('calling __init__')
super().__init__()
class C(object):
__init__ = __init__
if __name__ == '__main__':
c = C()
它失败是因为super()
查找一个__class__
cell,在本例中没有定义。在
是否可以在定义函数后手动设置此单元格,或者不可能?
不幸的是,我不明白细胞在这种情况下是如何工作的(没有找到很多相关的文档)。我希望像
^{pr2}$当然,我只会在类赋值明确/唯一的情况下使用它(在我的例子中,向中的类添加方法的整个过程是自动化的,因此添加这样一行会很简单)。在
也许吧,但你会吗?在这两种情况下,你需要以某种方式明确它是哪一个类,因为隐式方法不起作用。也许你可以显式地设置单元格,但是没有理由这么做。只需显式地传递参数。在
(如果你可以直接在实际的课堂上通过,比如:
^{pr2}$但是如果你能做到,你可以直接把
__init__
放在C
上,所以假设你不能说真的:你真的不想这么做。在
但是,对于Python的高级用户来说理解这一点是很有用的,所以我将对此进行解释。在
Cells和freevar是在创建闭包时指定的值。例如
^{pr2}$f
返回基于func
的闭包,存储对a
的引用。该引用存储在一个单元中(实际上是在一个freevar中,但是哪个单元取决于实现)。您可以检查:(“细胞”和“自由变量”非常相似。freevar有名称,其中单元格有索引。它们都储存在
func.__closure__
中,细胞是第一位的。这里我们只关心freevars
,因为这就是__class__
是什么。)一旦理解了这一点,就可以看到super()实际上是如何工作的。任何包含对
super
的调用的函数实际上都是一个闭包,其中有一个名为__class__
的freevar(如果您自己引用__class__
也会添加该值):(警告:这是事情变得邪恶的地方。)
这些细胞在
func.__closure__
中可见,但它是只读的;您无法更改它。更改它的唯一方法是创建一个新函数,这是用types.FunctionType
构造函数完成的。但是,您的__init__
函数根本没有__class__
自由变量,因此我们需要添加一个。这意味着我们还必须创建一个新的代码对象。在下面的代码就是这样做的。我添加了一个基类
B
,以便于说明。这段代码做了一些假设,例如__init__
还没有一个名为__class__
的自由变量。在这里还有另一个问题:似乎没有单元类型的构造函数。为了解决这个问题,我们创建了一个伪函数
C.dummy
,它有我们需要的cell变量。在你可以使用函数的字典。在
如果不想在函数内部硬编码成员的名称,甚至可以添加另一个属性
member_name
。在相关问题 更多 >
编程相关推荐