您似乎将 type 与内置的 type() 混淆了。在这里,他们只是引用传递给super() 的第一个参数。
文档告诉你的是 if 你传入了两个参数,那么第二个参数 either 必须是第一个参数的实例,或者 它必须是一个子类。换句话说,isinstance(first_argument, second_argument) 或 issubclass(first_argument, second_argument) 必须为真。 这里没有别的意思。
就像int() 或str() 或任何其他内置类型一样,调用super() 返回的对象的类型就是那个类型。没有为不同的参数返回单独的类型。请参阅C source code defining the object。
super() 对象实现了一个实现特定属性行为的__getattribute__ hook。文档告诉您属性查找的 规则 与 getattr() 相同(但有文档记录的 MRO 跳过),但 not 是否意味着 super()返回一个祖先类。
实际发生的情况是 super().__getattribute__ 采用第二个参数的 MRO(type(instance).__mro__ 或 cls.__mro__,取决于 isinstance() 或 issubclass() 是否为真),找到该序列中的第一个参数并之后开始测试属性。因为首先扫描 MRO 以查找第二个参数的(类型),所以它必须是可找到的,这就是约束是什么的原因。
在纯 Python 中,这就是 super() 所做的(简化为只关注两个参数行为):
def _supercheck(type_, obj):
try:
if issubclass(obj, type_):
return obj
except TypeError:
# obj is not a type so issubclass throws a TypeError
pass
if isinstance(obj, type_):
return type(obj)
raise TypeError(
"super(type, obj): obj must be an instance or subtype of type")
class super_:
def __init__(self, type_, obj):
# simplified for the two-argument case
self.type_ = type_
self.obj = obj
self.obj_type = _supercheck(type_, obj)
def __getattribute__(self, name):
if name == '__class__':
# __class__ should always come from this object, not
# the represented MRO.
return super().__getattribute__(name)
# avoid infinite recursion issues
sd = super().__getattribute__('__dict__')
starttype = sd['obj_type']
type_ = sd['type_']
obj = sd['obj']
mro = iter(starttype.__mro__)
# skip past the start type in the MRO
for tp in mro:
if tp == type_:
break
# Search for the attribute on the remainder of the MRO
for tp in mro:
attrs = vars(tp)
if name in attrs:
res = attrs[name]
# if it is a descriptor object, bind it
descr = getattr(type(res), '__get__', None)
if descr is not None:
res = descr(
res,
None if obj is starttype else obj,
starttype)
return res
return super().__getattribute__(name)