从这里:
super( [ type [ , object-or-type ]] )
返回将方法调用委托给的父级或同级类的代理对象
type
。这对于访问已在类中重写的继承方法很有用。搜索顺序与所使用的顺序相同,getattr()
只是type
略过了本身。如果省略第二个参数,则返回的超级对象是未绑定的。
如果第二个参数是一个对象,则
isinstance(obj, type)
必须为true。如果第二个参数是type,则
issubclass(type2, type)
必须为true(这对于类方法很有用)。
如果我是对的,则类型是类,而类是类型。类是对象,所以类型也是对象。当第二个参数是对象时,为什么引号区分这两种情况?
当第二个参数是类型时,为什么issubclass(type2, type)
必须为真?
这super
三种情况分别返回的超级对象的类型是什么?或如何确定由返回的超级对象的类型super
?
当第二个参数是一个对象时,因为“搜索顺序与它使用的搜索顺序相同,getattr()
只是它type
自身被跳过”,所以我猜测super
函数返回的超对象的类型应该是第一个参数的任何祖先类的子类。type
但是我发现实际上不是通过使用进行测试issubclass
。那我误会了吗?
您似乎将这个词type
与type()
内置混淆了。在这里,他们只是引用传递给的第一个参数super()
。
文档告诉您的是,如果您传入两个参数,则第二个参数要么必须是第一个参数的实例,要么必须是子类。换句话说,无论是isinstance(first_argument, second_argument)
或issubclass(first_argument, second_argument)
必须是真实的。这里没有其他含义。
与int()
或str()
其他任何内置类型一样,通过调用返回的对象的类型super()
就是那个type。没有为不同的参数返回单独的类型。请参见定义对象的C源代码。
该super()
对象实现一个实现特定属性行为的__getattribute__
钩子。该文件告诉你的是,规则的属性查找是一样的getattr()
(但与记录MRO跳过),但这并不意味着super()
收益的祖先类。
实际发生的是,super().__getattribute__
采用第二个参数的MRO(无论是type(instance).__mro__
或cls.__mro__
,取决于羯羊isinstance()
或issubclass()
为真),发现该序列的第一个参数,并开始测试了之后的属性。因为首先要对MRO扫描第二个参数的(类型),所以它必须是可找到的,这就是为什么约束是它们的原因。
在Pure 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)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句