这是superGuido 内置的纯python实现,用于说明目的.我需要对Super下面的课程实施做一些澄清
在下面的代码中调用someobj.__mro__将不起作用.看到我对这条线的评论.内置super只是一个错误被抛出.
TypeError: super(type, obj): obj must be an instance or subtype of type
题:
我的问题是,首先要有这条线的意图是什么?
因此,如果传入的对象不是传入类的实例,那么开始使用对象的mro ...为什么?
class Super(object):
def __init__(self, type, obj=None):
self.__type__ = type
self.__obj__ = obj
def __get__(self, obj, type=None):
if self.__obj__ is None and obj is not None:
return Super(self.__type__, obj)
else:
return self
def __getattr__(self, attr):
if isinstance(self.__obj__, self.__type__):
starttype = self.__obj__.__class__
else:
starttype = self.__obj__ ## This line does not work
mro = iter(starttype.__mro__)
for cls in mro:
if cls is self.__type__:
break
# Note: mro is an iterator, so the second loop
# picks up where the first one left off!
for cls in mro:
if attr in cls.__dict__:
x = cls.__dict__[attr]
if hasattr(x, "__get__"):
x = x.__get__(self.__obj__)
return x
raise AttributeError, attr
class A(object):
def m(self):
''' m in A'''
return "A"
class B(A):
def m(self):
''' m in B'''
return "B" + Super(B, self).m()
class C(A):
def m(self):
''' m in C '''
return "C" + Super(C, self).m()
class D(C):
def m(self):
''' m in D'''
return "D" + Super(B, self).m()
print D().m() # "DCBA"
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
Traceback (most recent call last):
File "./supertest.py", line 73, in <module>
print D().m() # "DCBA"
File "./supertest.py", line 71, in m
return "D" + Super(B, self).m()
File "./supertest.py", line 33, in __getattr__
mro = iter(starttype.__mro__)
AttributeError: 'D' object has no attribute '__mro__'
Run Code Online (Sandbox Code Playgroud)
TypeError: super(type, obj): obj must be an instance or subtype of type
您传递的对象obj是旧式对象(旧式类的实例).这些都具有类型classobj,并且不是类型的子类,object也不是类型type(或其子类type).
虽然在描述完旧代码和异常时,删除文本在旧样式对象的描述中是正确的,但这不是导致该异常的问题.上面的例外内置super捕获下面指出的错误:D不是它的子类B,因此super它告诉你它不能对这对输入做任何事情.
我的问题是,首先要有这条线的意图是什么?
触发回溯的问题(完全回溯,而不是上面讨论的第一个错误)D是不是它的子类B.
在这段代码中:
if isinstance(self.__obj__, self.__type__):
starttype = self.__obj__.__class__
else:
starttype = self.__obj__ ## This line does not work
mro = iter(starttype.__mro__)
Run Code Online (Sandbox Code Playgroud)
假设if if __obj__不是一个实例__type__,那么__obj__它本身就是一个类型,并且它有一个mro.对于你提供的类型不是基类(或类)的情况,没有处理程序__obj__,因为没有什么super(或Super)可以合理地使用它.
这里唯一的设计缺陷是构造函数应该捕获这种情况,并生成一个适当的异常.
最后,我注意到您发布的代码与您链接的文档中的代码不同.Guido的代码实际上并没有触发这个问题.