相关疑难解决方法(0)

为什么 super() 没有实现 __call__?

想象一下python 3中的以下情况(我使用的是3.6):

class T(object):
    def __call__(self):
        return 5

class U(T):
    def __call__(self):
        return 10 + super()()

U()()
Run Code Online (Sandbox Code Playgroud)

这导致TypeError: 'super' object is not callable.

使其工作需要U定义如下:

class U(T):
    def __call__(self):
        return 10 + super().__call__()
Run Code Online (Sandbox Code Playgroud)

为什么第一个版本不起作用?我发现了这个相关的问题,但它没有回答这个问题。其实这个问题也在评论里问的有答案。

进一步阅读super() 实际返回的内容给我的印象是,返回的代理super()必须实现__call__并转发到正确的__call__实现。从这个答案中,我得到返回的代理对象super()只有一个__getattribute__方法可以返回任何父对象的正确函数。

如果我理解正确,这意味着代理只需要实现以下内容即可super()()工作:

def __call__(self, *args, **kwargs):
    try:
        return self["__call__"](*args, **kwargs)  # not sure if self is already bound to the method, if not that …
Run Code Online (Sandbox Code Playgroud)

python inheritance super

9
推荐指数
0
解决办法
716
查看次数

在一般情况下,Python的super()实际上是如何工作的?

有很多很棒的资源super(),包括这篇很棒的博客文章,以及关于Stack Overflow的很多问题.但是我觉得他们都没有解释它在最常见的情况下是如何工作的(使用任意继承图),以及在幕后发生的事情.

考虑这个钻石继承的基本例子:

class A(object):
    def foo(self):
        print 'A foo'

class B(A):
    def foo(self):
        print 'B foo before'
        super(B, self).foo()
        print 'B foo after'

class C(A):
    def foo(self):
        print 'C foo before'
        super(C, self).foo()
        print 'C foo after'

class D(B, C):
    def foo(self):
        print 'D foo before'
        super(D, self).foo()
        print 'D foo after'
Run Code Online (Sandbox Code Playgroud)

如果从像源Python的规则,方法解析顺序读了这个或查找的维基百科页面的C3线性化,你会看到,MRO必须(D, B, C, A, object).这当然得到以下证实D.__mro__:

(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) …
Run Code Online (Sandbox Code Playgroud)

python oop multiple-inheritance super method-resolution-order

3
推荐指数
1
解决办法
397
查看次数