it_*_*ure 4 python multiple-inheritance superclass python-3.x
创建一个son有两个父类的类:
class mon():
def __new__(cls):
print("i am in mon's new")
return super().__new__(cls)
def __init__(self):
print("i am in mon's init")
super().__init__()
class far():
def __new__(cls):
print("i am in far's new")
return super().__new__(cls)
def __init__(self):
print("i am in far's init")
class son(mon,far):
def __init__(self):
super().__init__()
Run Code Online (Sandbox Code Playgroud)
初始化son类以检查发生了什么。
super().__init__()在son类中会调用__init__方法in mon,在in__new__之前执行的方法,in ,它使代码跳转到类,在in之前执行的方法,代码跳回打印并跳转到打印,所以我们得到以下输出。__init__monsuper().__new__(cls)monfar__new____init__farmoni am in mon's initfari am in far's init
son_instance = son()
i am in mon's new
i am in far's new
i am in mon's init
i am in far's init
Run Code Online (Sandbox Code Playgroud)
问题1:
在初始化类时如何重写三个类结构以获得如下输出son?
son_instance = son()
i am in mon's new
i am in mon's init
i am in far's new
i am in far's init
Run Code Online (Sandbox Code Playgroud)
删除类中的语句far:
return super().__new__(cls)
Run Code Online (Sandbox Code Playgroud)
整个三个类如下:
class mon():
def __new__(cls):
print("i am in mon's new")
return super().__new__(cls)
def __init__(self):
print("i am in mon's init")
super().__init__()
class far():
def __new__(cls):
print("i am in far's new")
class son(mon,far):
def __init__(self):
super().__init__()
Run Code Online (Sandbox Code Playgroud)
son再次初始化类。
x=son()
i am in mon's new
i am in far's new
Run Code Online (Sandbox Code Playgroud)
问题2:
为什么代码无法跳回mon类?为什么无法得到以下输出?
x=son()
i am in mon's new
i am in far's new
i am in mon's init
Run Code Online (Sandbox Code Playgroud)
如果类return super().__new__(cls)中没有,则只在类中far生效,但是类中根本没有方法,为什么会导致类中没有调用方法呢?__init__far__init__far__init__mon
让我试着一一回答你的两个问题。
当初始化子类时,如何重写三个类结构以获得如下输出?
你不能。您的代码需要先使用这些__new__方法创建新实例,然后才能开始使用这些__init__方法初始化实例。如果您希望行为以其他顺序运行,则需要在其他地方执行此操作。您无法调整继承层次结构以使其正常工作。
为什么代码无法跳回 mon 类?为什么无法得到以下输出?
您的代码无法正常工作,因为far.__new__已损坏(可能是因为您在删除方法时稍微过于热心__init__并删除了额外的一行)。该__new__方法不返回任何内容,相当于返回None. 如果__new__方法不返回正在创建的类的实例,则__init__永远不会调用该方法。__new__如果您通过重新添加 in 来修复该方法return super().__new__(cls),您将获得预期的输出。
即使far类本身没有__init__方法,也会发生这种情况。外部代码(type.__call__在本例中)不知道整个继承层次结构并依次调用每个函数。它只调用正在创建的类上的方法,并且它相信如果合适的话,实现将调用该函数的父类版本。如果son.__new__(继承的)像被破坏None时一样返回far.__new__,那么就son.__init__不会像__new__方法正常工作时那样被调用。
这是一个非常近似的纯 Python 版本type.call(实际版本是用 C 实现的):
def __call__(cls, *args): # this is in a metaclass, so I use cls instead of self
obj = cls.__new__(*args)
if isinstance(obj, cls):
obj.__init__(*args)
return obj
Run Code Online (Sandbox Code Playgroud)
我遗漏了很多额外的内容,例如如何type(obj)获取现有实例的类型,而不是创建新类型。但常规实例创建时的行为如图所示。
如果需要,您可以在Python 源代码存储库中阅读完整的详细信息(C 语言) 。type.__call__(called )的 C 版本type_call检查返回的对象cls.__new__类型是否正确的部分位于此处。
| 归档时间: |
|
| 查看次数: |
624 次 |
| 最近记录: |