【问题标题】:what is super(type) in python?python中的超级(类型)是什么?
【发布时间】:2014-04-28 07:27:56
【问题描述】:

类定义:

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


class B(object):
    def foo(self):
        print "B" 


class C(A, B): 
    def foo(self):
        print "C"

输出:

>>> super(C)
<super: <class 'C'>, NULL>
>>> super(C).foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'foo'

如果我们不能访问类的属性,那么 super(type) 有什么用?

【问题讨论】:

    标签: python inheritance super


    【解决方案1】:

    要完成你想要的,你需要这样称呼它:

    >>> myC = C()
    >>> super(C,myC).foo()
    A
    

    【讨论】:

      【解决方案2】:

      请注意,有一个NULL 对某个对象的引用。它基本上需要一个类一个相关对象的实例才能发挥作用。

      >>> super(C, C()).foo
      <bound method C.foo of <__main__.C object at 0x225dc50>>
      

      有关详细信息,请参阅:Understanding Python super() with __init__() methods

      【讨论】:

        【解决方案3】:

        super(type) 是一个“未绑定”的超级对象。 super 上的文档对此进行了讨论,但并没有真正详细说明“未绑定”超级对象是什么或做什么。这只是语言的一个事实,您无法以您尝试使用它们的方式使用它们。

        这也许就是你想要的:

        >>> super(C, C).foo is B.foo
        True
        

        也就是说,未绑定的超级对象有什么用?我不得不自己查一下,找到了一个不错的答案here。但是请注意,文章的结论是 unbound super 是一种语言缺陷,没有实际用途,应该从语言中删除(阅读文章后,我同意)。文章对unbound super的解释是这样开头的:

        必须将未绑定的超级对象转换为绑定对象才能使它们正确调度。这可以通过描述符协议来完成。例如,我可以通过这种方式在绑定到 c1 的超级对象中转换 super(C1):

        >>> c1 = C1()
        >>> boundsuper = super(C1).__get__(c1, C1) # this is the same as super(C1, c1)
        

        所以,这似乎没有用,但文章继续:

        确定未绑定语法不返回未绑定方法后,您可能会问它的目的是什么。答案是super(C) 旨在用作其他类中的属性。然后描述符魔术会自动将未绑定语法转换为绑定语法。例如:

        >>> class B(object):
        ...     a = 1
        >>> class C(B):
        ...     pass
        >>> class D(C):
        ...     sup = super(C)
        >>> d = D()
        >>> d.sup.a
        1
        

        这有效,因为d.sup.a 调用super(C).__get__(d,D).a 转换为super(C, d).a 并检索B.a

        据我所知,super 的单参数语法有一个用例,但我认为它带来的麻烦多于优势。用例是 Guido 在他关于 new-style classes 的文章中提出的 autosuper 的实现。

        这里的想法是使用未绑定的超级对象作为私有属性。例如,在我们的示例中,我们可以将 C 类中的私有属性 __sup 定义为未绑定的超级对象 super(C)

        >>> C._C__sup = super(C)
        

        但是请注意,文章继续描述了这个问题(它不能完全正常工作,我认为主要是因为 MRO 依赖于您正在处理的实例的类,因此给定一个实例,某些类 X 的超类可能会根据给定的 X 实例而有所不同。

        【讨论】:

        • +1。我认为值得一提的是那篇博文的主要内容,即未绑定的超级对象几乎没有实际用途。这基本上是 OP 问题的答案。
        • @BrenBarn 我试图让文章中关于 super 实际使用的观点更加明显。
        猜你喜欢
        • 1970-01-01
        • 2011-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-24
        • 2019-11-15
        • 1970-01-01
        • 2022-01-19
        相关资源
        最近更新 更多