Dre*_*man 4 python multiple-inheritance python-3.x
我有三个课程如下:
class Page(object):
def __init__(self, Obj_a, Obj_b):
super().__init__(Obj_a, Obj_b)
class Report(object):
def __init__(self, Obj_a, Obj_b):
super().__init__()
class ReportingPage(Page,Report):
def __init__(self, Obj_a, Obj_b):
super().__init__(Obj_a, Obj_b)
Run Code Online (Sandbox Code Playgroud)
我实例化一个ReportingPage对象.要做到这一点,Python爬行MRO:
Page首先调用该对象,因为它首先在继承列表中排序ReportingPage,然后调用它自己的__init__方法.
然后它也是这样做的Report.
我不明白的两件事:
为什么我必须将参数传递给super.__init__in Page,什么Page时候才会调用__init__它继承的内容,object.
为什么我不必为此做同样的事情Report.
super()查看当前实例的MRO .这里没有关系,当前类只继承自object.
的MRO ReportingPage看跌期权Report之间Page和object:
>>> ReportingPage.__mro__
(<class '__main__.ReportingPage'>, <class '__main__.Page'>, <class '__main__.Report'>, <class 'object'>)
Run Code Online (Sandbox Code Playgroud)
所以,当你打电话super()的Page.__init__(),在MRO下一类是Report,你最终调用的Report.__init__方法.
你需要让你的课程更合作; 你可以使用关键字参数和一个catch-all **kwargs参数来做到这一点:
class Page(object):
def __init__(self, pagenum, **kwargs):
self.pagenum = pagenum
super().__init__(**kwargs)
class Report(object):
def __init__(self, title, **kwargs):
self.title = title
super().__init__(**kwargs)
class ReportingPage(Page, Report):
def __init__(self, footer=None, **kwargs):
self.footer = footer
super().__init__(**kwargs)
Run Code Online (Sandbox Code Playgroud)
每个方法都将此处的剩余关键字参数传递给__init__MRO中的下一个,最后您将有一个空字典传递给它object.__init__().如果print(kwargs)为每个__init__方法添加一个包装器,您可以看到kwargs随着较少的值传递给下一个调用而变小.
>>> def print_wrapper(name, f):
... def wrapper(*args, **kwargs):
... print(name, '->', kwargs)
... return f(*args, **kwargs)
... return wrapper
...
>>> for cls in ReportingPage.__mro__[:-1]: # all except object
... cls.__init__ = print_wrapper(cls.__name__, cls.__init__)
...
>>> ReportingPage(title='Watching Paint Dry II: The Second Coat', pagenum=42)
ReportingPage -> {'title': 'Watching Paint Dry II: The Second Coat', 'pagenum': 42}
Page -> {'title': 'Watching Paint Dry II: The Second Coat', 'pagenum': 42}
Report -> {'title': 'Watching Paint Dry II: The Second Coat'}
<__main__.ReportingPage object at 0x109e3c1d0>
Run Code Online (Sandbox Code Playgroud)
只有title保持,这Report.__init__()消耗,所以一个空的kwargs字典传递给object.__init__()
您可能对Raymond Hettinger的超级考虑超级感兴趣,包括他的PyCon 2015演示.
| 归档时间: |
|
| 查看次数: |
139 次 |
| 最近记录: |