【问题标题】:Initialize instance variable in a mixin在 mixin 中初始化实例变量
【发布时间】:2023-03-14 08:29:01
【问题描述】:

我想为使用mixin 的类提供一些功能。该功能使用一些额外的每个对象状态。我想知道初始化这个本地状态的最干净的方法是什么。考虑这个例子:

class Mixin:
    items = []
    def append(self, x):
        self.items.append(x)
    def display(self):
        print self.items

class Foo(object, Mixin): pass
class Bar(object, Mixin): pass

foo = Foo()
foo.append('foo')
foo.display()

>>> ['foo']

bar = Bar()
bar.append('bar')
bar.display()

>>> ['foo', 'bar']

这里,状态是items 列表。在 Mixin 主体中初始化它显然是错误的。通常,我会在 __init__ 中初始化它,但使用 Mixin 我不想与 __init__ 混淆。

我可以做到以下几点:

class Mixin:
    items = None

def append(self, x):
    if self.items is None:
        self.items = []
    self.items.append(x)

但条件是在每个append 上评估的,它似乎不是最干净的解决方案。

还有其他选择吗?或者也许将__init__ 添加到mixin 中是这样的?

(是否使用 mixins 是一个单独的问题)

相关

【问题讨论】:

    标签: python


    【解决方案1】:

    我建议把它放在 Mixin 的 __init__() 中。你觉得缺点是什么?

    class Mixin(object):
        def __init__(self, *args, **kwargs):
            super(Mixin, self).__init__(*args, **kwargs)
            self.items = []
    

    我认为这是正确的做法;所有其他(可能有效)解决方案对我来说都像是一个 hack。

    【讨论】:

    • 应该从对象继承mixin吗?
    • 我假设你的意思是Mixin是否应该继承object;我要回答这个问题。如果没有object 的继承,该类将是一个老式类。为了正确使用super(),应该是新式类,所以继承object,是的。
    • 您可以在 Python 3 中省略该对象,但无论如何都要包含它,因此您的代码也可以在 Python 2 上运行。
    • mixin 的类型真的很重要吗?它永远不会被实例化,当混合到新样式类中时,该类仍然是新样式。
    【解决方案2】:

    最干净的解决方案是添加一个__init__ 方法并在每个方法中使用super() 以确保每个方法都被调用。

    class Mixin:
        def __init__(self, *args, **kwargs):
            self.items = []
            super(Mixin, self).__init__(*args, **kwargs)
        def append(self, x):
            self.items.append(x)
        def display(self):
            print self.items
    

    【讨论】:

    • super 需要类继承object 才能正常工作。
    • 啊,谢谢 Blubber。很高兴知道。另一方面,这篇文章并不是专门针对 Python3 的。
    • 是的,在 Python 3 中你可以添加对象,但它实际上并没有做任何事情,所以无论如何添加它是个好主意。
    • 是的,这是改变构造函数签名的老问题。 sigh 我知道没有好的解决方案。我通常使用的一种方法是让每个构造函数混淆它理解的所有输入部分(它“消耗”它们)并只传递它不知道的部分。这样object__init__() 将收到一个空的kwargs,它不会抱怨。
    • 看看pastebin.com/MieUwp3p 了解我的意思(如果还不清楚的话)。
    猜你喜欢
    • 2012-09-17
    • 1970-01-01
    • 2010-10-18
    • 2011-06-21
    • 2013-08-14
    • 2017-04-05
    • 2011-03-18
    • 2010-11-26
    • 1970-01-01
    相关资源
    最近更新 更多