从这里:
Run Code Online (Sandbox Code Playgroud)super( [ type [ , object-or-type ]] )返回一个代理对象,该方法将方法调用委托给父类或兄弟类
type.这对于访问已在类中重写的继承方法很有用.搜索顺序与使用的搜索顺序相同,getattr()只是type跳过了自身.如果省略第二个参数,则返回的超级对象是未绑定的.
如果第二个参数是一个对象,则
isinstance(obj, type)必须为true.如果第二个参数是一个类型,则
issubclass(type2, type)必须为true(这对于classmethods很有用).
如果我是正确的,则类型是类,类是类型.类是一个对象,因此类型也是一个对象.当第二个参数是一个类型的对象时,为什么引用会区分这两种情况?
当第二个参数是一个类型时,为什么issubclass(type2, type)
要求为真?
super分别在三种情况下返回的超级对象的类型是什么?或者你如何确定返回的超级对象的类型super?
当第二个参数是一个对象时,因为"搜索顺序与getattr()除了type自身被跳过之外的搜索顺序相同",我猜测super函数返回的superobject的类型应该是第一个参数的任何祖先类的子类type,但我发现它实际上不是通过测试issubclass.所以我误解了什么?
您似乎将这个词type与type()内置词混淆了。在这里,他们只是引用传入的第一个参数super()。
文档告诉你的是,如果你传入两个参数,那么第二个参数要么必须是第一个参数的实例,要么必须是一个子类。换句话说,要么isinstance(first_argument, second_argument)或issubclass(first_argument, second_argument)必须为真。这里没有其他含义。
就像int()orstr()或任何其他内置类型一样,调用返回的对象的类型super() 就是 type。没有为不同的参数返回单独的类型。请参阅定义对象的C 源代码。
该super()对象实现了一个__getattribute__钩子,该钩子实现了特定的属性行为。该文件告诉你的是,规则的属性查找是一样的getattr()(但与记录MRO跳过),但这并不意味着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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
956 次 |
| 最近记录: |