简体   繁体   English

Python Mixins:*args/**kwargs vs 显式调用`__init__`

[英]Python Mixins: *args/**kwargs vs explicit call to `__init__`

I try to write an example of Mixins using Clickable and Rectangle classes, which are superclasses of the Button class.我尝试使用ClickableRectangle类编写一个 Mixins 示例,它们是Button class 的超类。

Currently I use:目前我使用:

class Clickable:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.clicks = 0

    def click(self):
        self.clicks = self.clicks + 1


class Rectangle:
    def __init__(self, x0, y0, x1, y1, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.upper_right = (x0, y0)
        self.lower_down = (x1, y1)


class Button(Clickable, Rectangle):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

But I consider using:但我考虑使用:

class Clickable:
    def __init__(self):
        self.clicks = 0

    def click(self):
        self.clicks = self.clicks + 1


class Rectangle:
    def __init__(self, x0, y0, x1, y1):
        self.upper_right = (x0, y0)
        self.lower_down = (x1, y1)


class Button(Clickable, Rectangle):
    def __init__(self, x0, y0, x1, y1):
        Rectangle.__init__(self, x0, y0, x1, y1)
        Clickable.__init__(self)

Is one of them is better for some reason?出于某种原因,其中之一更好吗?

The recommended way (see https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ ) is to use keyword arguments to avoid conflicts between which parent is expected to be passed which positional arguments. The recommended way (see https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ ) is to use keyword arguments to avoid conflicts between which parent is expected to be passed which positional arguments.

class Clickable:
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.clicks = 0

    def click(self):
        self.clicks = self.clicks + 1


class Rectangle:
    def __init__(self, x0, y0, x1, y1, **kwargs):
        super().__init__(**kwargs)
        self.upper_right = (x0, y0)
        self.lower_down = (x1, y1)


class Button(Clickable, Rectangle):
    # No need to override __init__ if all it does
    # is pass all its arguments to the next invocation
    pass


b = Button(x0=0, y0=0, x1=10, y1=10)

Remember, the reason for accepting arbitrary keyword arguments and passing them on in the first place is that you don't know which class super() will produce, so you can't predict the expected signature.请记住,接受任意关键字 arguments 并首先传递它们的原因是您不知道哪个 class super()会产生,因此您无法预测预期的签名。

Mixins are nearly, by definition, expected to support cooperative inheritance, because they are expected to be used with multiple inheritance and someone will probably want to use your mixin in a class that does.根据定义,mixin 几乎有望支持协作 inheritance,因为它们预计将与多个 inheritance 一起使用,并且有人可能希望在 class 中使用您的 mixin。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM