来自here:
super( [ type [ , object-or-type ]] )
返回一个代理对象,该方法将方法调用委托给
type
的父类或兄弟类。这对于访问已在类中重写的继承方法很有用。搜索顺序与getattr()
使用的搜索顺序相同,只是跳过type
本身。如果省略第二个参数,则返回的超级对象是 绑定。
如果第二个参数是一个对象,
isinstance(obj, type)
必须是 真正。如果第二个参数是类型,则必须是
issubclass(type2, type)
true(这对于classmethods很有用。)
如果我是正确的,则类型是类,类是类型。一类 是一个对象,所以类型也是一个对象。为什么报价 当第二个参数是一个对象时,区分这两种情况 当它是一种类型?
当第二个参数是一个类型时,为什么issubclass(type2, type)
要求是真的吗?
这三种情况分别由super
返回的超级对象的类型是什么?或者如何确定super
返回的超级对象的类型?
当第二个参数是一个对象时,因为"搜索顺序与getattr()
使用的搜索顺序相同,只是type
本身被跳过",我猜这个类型super
函数返回的superobject应该是第一个参数type
的任何祖先类的子类,但我发现它实际上不是通过issubclass
测试。那么我误解了什么吗?
答案 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'>