python - 使用 kwargs 进行多重继承
问题描述
问题
我在Dusty Phillips的面向对象编程中遇到了这段代码(为简洁起见),我不确定这个定义的特定部分。
class A:
def __init__(self, a, **kwargs):
super().__init__(**kwargs)
self.a = a
class B:
def __init__(self, b, **kwargs):
super().__init__(**kwargs)
self.b = b
class C(A, B):
def __init__(self, c, **kwargs):
super().__init__(**kwargs)
self.c = c
问题
- 既然方法解析顺序是
(__main__.C, __main__.A, __main__.B, object)
, 可以class B
改为下面的方式定义吗?
class B:
def __init__(self, b):
self.b = b
- 不是多余
super().__init__(**kwargs)
的class B
,因为任何多余kwargs
的传递给C
将传递给object
,提高?
TypeError: object.__init__() 只接受一个参数(要初始化的实例)
- 这是 if
C
被定义为class C(B, A)
而不是的保障class C(A, B)
吗?
解决方案
考虑如何实例化C
:
c = C(a=3, b=5, c=9)
C.__init__
获取所有关键字参数,但只使用一个作为自己的参数c
。其余的将传递给__init__
链中的下一个方法。在这种情况下,那是A.__init__
,它“拉出”参数a
并传递b
给B.__init__
。B
使用它并将(现在为空的)关键字参数集传递给下一个方法,object.__init__
. 因为所有关键字参数都已“声明”并由其他类处理,所以object.__init__
成功。
由于 MRO 的构造方式,正确使用super()
保证的类到那时**kwargs
将是空的object.__init__
。
推荐阅读
- html - 可滚动的弹性项目 - 如何让宽度等于内容
- typescript - Typescript 使用派生类作为方法的返回类型
- ruby-on-rails - Ruby on rails:如何从机架中间件身份验证中排除某些路径?
- laravel - 如何在 Laravel 中为用户显示相应的登录页面?
- postgresql - “QueryFailedError:整数的输入语法无效:”查询浮点类型时
- azure-devops - 解决 UserStory 时自动化,将视频从附件上传到 Yammer 作为新帖子作为附件。美国的标题将是内容
- html - 找不到未禁用的字段“player_1_name”
- entity-framework - 将 SQL 命令转换为 lambda 表达式
- javascript - 二进制数据文件下载 JavaScript 中的任何扩展
- azure - 提醒我如何从函数应用程序向销售人员对象发送数据?