Python 3.x 使用ABC模块时,关键字参数是一种好的做法吗?

Python 3.x 使用ABC模块时,关键字参数是一种好的做法吗?,python-3.x,inheritance,super,Python 3.x,Inheritance,Super,这个问题,是一个后续问题 使用的super()时,建议的方法是使用关键字参数将剩余值向上传递到调用链 使用ABC模块时,在super()中使用相同的方法是否是一种良好的做法 关于super()的Python文档链接到的博客文章没有提到任何关于使用**kwargs和ABC模块的内容。它主要关注具有具体类的多重继承。为了重新表述我的问题,关于将**kwargs与super()一起使用的建议是否适用于使用ABC模块的类 例如: from abc import ABC class GameWeapo

这个问题,是一个后续问题

使用的
super()
时,建议的方法是使用关键字参数将剩余值向上传递到调用链

使用
ABC
模块时,在
super()中使用相同的方法是否是一种良好的做法

关于
super()
的Python文档链接到的博客文章没有提到任何关于使用
**kwargs
ABC
模块的内容。它主要关注具有具体类的多重继承。为了重新表述我的问题,关于将
**kwargs
super()
一起使用的建议是否适用于使用
ABC
模块的类

例如:

from abc import ABC


class GameWeapon(ABC):

    def __init__(self, name, damage, **av):
         super().__init__(**av)
         self.name = name
         self.required_strength = required_strength
         self.damage = damage


class ChargeGun(GameWeapon):

    def __init__(self, name, required_strength, damage, **av):
        super().__init__(name=name,damage=damage,**av)

让我们看看你提到的博客文章中的特定实例

class Shape:
    def __init__(self, shapename, **kwds):
        self.shapename = shapename
        super().__init__(**kwds)

class ColoredShape(Shape):
    def __init__(self, color, **kwds):
        self.color = color
        super().__init__(**kwds)

cs = ColoredShape('red', shapename='circle', radius=30)
TypeError: object.__init__() takes no arguments
创建
ColoredShape
对象时,需要输入颜色和shapename。如果您传递了一个意外的关键字参数,它将给您一个错误。这是因为all(在Python3中)继承自内置类型
对象
,该对象具有不需要参数的
\uuuu init\uuuu

正如文章所指出的,
object
保证是MRO中调用的最后一个类。但是,如果您删除了对super in Shape的调用,您可以添加任意数量的关键字参数而不会出现问题,即使它们不会用于任何用途

class Shape:
    def __init__(self, shapename, **kwds):
        self.shapename = shapename

class ColoredShape(Shape):
    def __init__(self, color, **kwds):
        self.color = color
        super().__init__(**kwds)

cs = ColoredShape('red', shapename='circle', radius=30, diameter=60)

在您发布的代码中,您是从abc继承的,abc不会通过super最后调用对象的init。因此,博客文章中显示的设计模式不适用于您的案例。我希望这能有所帮助。

你所说的“适当”是什么意思?你对“适当”有什么可以衡量的概念吗?@RobertHarvey-我指的是与博客和上一个答案中给出的建议相关的正确或良好的实践。这只是在重复“适当”。你认为适当的标准是什么?关于你之前的问题,你在旁边打勾的答案是“super()需要你的代码配合。你的武器和可重新加载的类不需要,所以你实际上不想在这里使用super()”,这是可行的建议。如果不说明原因,简单地说某事是“适当的”或“最佳实践”是不可行的。相反地,在不知道您的目标的情况下很难回答您的问题。我想说,您的代码中不需要使用关键字参数,因为您可以简单地执行
super()。在我看来,这也更具可读性。换句话说,在
super()
中不需要
kwargs
?对的我只是传入了基构造函数需要的内容,并将其保留。@EmilyScott:但要考虑到,在类继承层次结构的不同级别使用类和基类可能会导致一个MRO,它将您认为的最后一个类放在更早的某个地方。您通常不会构建这样的层次结构,但是。如果您的类要用作混合类,那么您需要通过调用
super()
来说明这一点,并且在
\uuuuu init\uuuuuu
调用链中,使用
**kwargs
是传递剩余参数的一种很好的方式。我同意Martijn Pieters指出的一切。将
**kwargs
向上传递到调用链可以减少需要非常长的
\uuuu init\uuuu
,这可能需要(比如)20个参数。@MartijnPieters-使用类在类继承层次结构的不同级别上的基类,您的意思是当您使用抽象类时,但该类不是继承层次结构的顶部,对的例如,抽象类继承了另一个抽象类?@EmilyScott:是的,或者当您使用从ABC继承的类作为更大层次结构中的mixin类时。使用mixin类并查看
\uuumro\uuuu
属性以查看它们的线性顺序。