super()返回的超级对象的类型是什么?

时间:2017-07-08 23:13:51

标签: python python-3.x

来自here

super( [ type [ , object-or-type ]] )
     

返回一个代理对象,该方法将方法调用委托给type的父类或兄弟类。这对于访问已在类中重写的继承方法很有用。搜索顺序与getattr()使用的搜索顺序相同,只是跳过type本身。

     

如果省略第二个参数,则返回的超级对象是   绑定。

     

如果第二个参数是一个对象,isinstance(obj, type)必须是   真正。

     

如果第二个参数是类型,则必须是issubclass(type2, type)   true(这对于classmethods很有用。)

  1. 如果我是正确的,则类型是类,类是类型。一类 是一个对象,所以类型也是一个对象。为什么报价 当第二个参数是一个对象时,区分这两种情况 当它是一种类型?

  2. 当第二个参数是一个类型时,为什么issubclass(type2, type) 要求是真的吗?

  3. 这三种情况分别由super返回的超级对象的类型是什么?或者如何确定super返回的超级对象的类型?

    当第二个参数是一个对象时,因为"搜索顺序与getattr()使用的搜索顺序相同,只是type本身被跳过",我猜这个类型super函数返回的superobject应该是第一个参数type的任何祖先类的子类,但我发现它实际上不是通过issubclass测试。那么我误解了什么吗?

2 个答案:

答案 0 :(得分:4)

您似乎将type这个词与type()内置词混淆了。在这里,他们只是引用传递给super()的第一个参数。

文档告诉你的是如果你传入两个参数,那么第二个参数要么必须是第一个参数的实例,它必须是一个子类。换句话说,isinstance(first_argument, second_argument)issubclass(first_argument, second_argument)必须为真。 这里没有其他含义

就像int()str()或任何其他内置类型一样,通过调用super() 返回的对象类型是类型。对于不同的参数,没有返回单独的类型。请参阅C source code defining the object

super()对象实现了一个实现特定属性行为的__getattribute__ hook。该文档告诉您,属性查找的规则getattr()相同(但记录的MRO跳过),但意味着{ {1}}返回一个祖先类。

实际发生的是super()获取第二个参数的MRO(super().__getattribute__type(instance).__mro__,具体取决于cls.__mro__isinstance()是否为真),找到该序列中的第一个参数,然后开始测试属性。因为MRO首先被扫描为第二个参数的类型,所以它必须是可查找的,这就是为什么约束就是它们的原因。

在Pure Python中,这是issubclass()所做的(简化为仅关注两个参数行为):

super()

答案 1 :(得分:2)

仅针对3个案例中关于超类型的点3(2个首先是类似的):

class A(object):
    def sup(self):
        return (super(A, self))

class A1(object):
    def sup(self):
        return (super())


class B(object):      
    def sup(self):
        return (super(B))  

class C(A):
    def sup(self):
        return (super(A,C))      

a = A()
a_sup = a.sup()
print(type(a_sup))  #<class 'super'>
print(a_sup.__doc__)  #The most base type
print(a_sup.__self__)  #<__main__.A object at 0x7f9d0d2d8668>
print(a_sup.__self_class__) #<class '__main__.A'>
print(a_sup.__thisclass__)  #<class '__main__.A'>

print()  
a1 = A1()
a_sup = a1.sup()
print(type(a_sup))  #<class 'super'>
print(a_sup.__doc__)  #The most base type
print(a_sup.__self__)  #<__main__.A1 object at 0x7f9d0d2d86d8>
print(a_sup.__self_class__) #<class '__main__.A1'>
print(a_sup.__thisclass__) #<class '__main__.A1'>

print()    
b = B()
b_sup = b.sup()
print(type(b_sup))  #<class 'super'>
print(b_sup.__doc__) 
'''
super() -> same as super(__class__, <first argument>)
super(type) -> unbound super object
super(type, obj) -> bound super object; requires isinstance(obj, type)
super(type, type2) -> bound super object; requires issubclass(type2, type)
Typical use to call a cooperative superclass method:
class C(B):
    def meth(self, arg):
        super().meth(arg)
This works for class methods too:
class C(B):
    @classmethod
    def cmeth(cls, arg):
        super().cmeth(arg)
'''        

print(b_sup.__self__)  #None
print(b_sup.__self_class__)  #None
print(b_sup.__thisclass__)  #<class '__main__.B'>

print()
c=C()
c_sup = c.sup()
print(type(c_sup))  #<class 'super'>
print(c_sup.__doc__) #The most base type
print(c_sup.__self__) #<class '__main__.C'>
print(c_sup.__self_class__) #<class '__main__.C'>
print(c_sup.__thisclass__) #<class '__main__.A'>