如果您在变量中保存对super的调用以供将来使用,会发生什么?

时间:2011-10-09 11:41:31

标签: python super

如果我对这里显而易见的事情一无所知,请原谅我,但是如果你在变量中保存对super的调用并稍后使用它会发生什么。

这是课程定义的一部分,向您展示我的意思。

class CaselessDict(dict):

    def __init__(self, *args, **kwargs):
        self.super = super(CaselessDict, self) # save super
        self.update(*args, **kwargs)

    def __getitem__(self, key):
        key = self.parsekey(key)
        return self.super.__getitem__(key) # use saved super

当我实现这个CaselessDict类并且几乎每个方法都有超级的时候出现了。

3 个答案:

答案 0 :(得分:4)

预期的事情发生了:self.super只会保留一个super对象,就像super(CaselessDict, self)一样。

这种方法的问题是每个实例只有一个super属性,所以如果你有更多的类可以使用这种技术,那么只有最后分配给super的那个才能正常运行。哎哟!所以,这样做通常不是一个好主意。您可以为属性__super命名,以便它被破坏,但我建议您像其他人一样调用super(CaselessDict, self)

当然,Python 3中的草更绿,只需简单的super()通话即可。

答案 1 :(得分:0)

宇宙会爆炸。不,不会发生任何错误,即使这不是通常的用法。为了记录,在Python 3中,您可以使用super().foo(...),因此在那里做起来基本没用。

答案 2 :(得分:0)

我有一个合法的案例,我来做这种事情,涉及动态加载和重新加载的类。这是一个片段,它加载包含A类的模块“a”,并创建它的实例:

>>> import imp
>>> m = imp.find_module("a")
>>> a = imp.load_module("a", *m)
>>> a.A
<class 'a.A'>
>>> aobj = a.A()
>>> aobj.__class__
<class 'a.A'>

现在如果我重新导入“a”,看看如果我用以前创建的aobj调用isinstance会发生什么:

>>> a = imp.load_module("a", *m)
>>> print a.A
<class 'a.A'>
>>> isinstance(aobj, a.A)
False

这与super有什么关系,就像Python 2.6一样,super(AClass,self)添加了检查以确保自引用确实是AClass的一个实例。在我的例子中,我在“A”的方法中使用了super,但是一旦“a”模块被重新导入并重新定义了“A”类,我的超级引用就不再起作用了! a.A类已更改为我现有的a.A实例不再是实例,因此super(a.A, self)将开始引发TypeErrors。为了解决这个问题,我基本上做了OP所做的事情:在__init__中,我将对super的引用保存到一个实例变量中,然后在其他方法中使用它来上调到基类方法。

这是我的全部(也许有点漫无边际)blog post