如何将“mixin”类应用于旧式基类

时间:2010-09-01 03:18:54

标签: python inheritance mixins

我写了一个mixin类,它被设计为在新式类之上分层,例如通过

class MixedClass(MixinClass, BaseClass):
    pass

将这种混合应用于旧式课程的最流畅的方法是什么?它在super方法中使用了对__init__的调用,因此这可能会(?)必须更改,但除此之外我想尽可能少地对MixinClass进行更改。我应该能够派生出一个进行必要更改的子类。

我正在考虑在派生自BaseClass的类之上使用类装饰器,例如

@old_style_mix(MixinOldSchoolRemix)
class MixedWithOldStyleClass(OldStyleClass)

其中MixinOldSchoolRemix派生自MixinClass,只是重新实现使用super的方法来改为使用包含与其混合的类的类变量,在本例中为{{ 1}}。作为混合过程的一部分,此类变量将由OldStyleClass设置。

old_style_mix只会更新例如old_style_mix包含mixin类的内容(例如MixedWithOldStyleClass)字典。

这是一个合理的策略吗?有没有更好的办法?这似乎是一个常见的问题,因为有许多可用的模块仍在使用旧式类。

1 个答案:

答案 0 :(得分:2)

  

此类变量将由。设置   old_style_mix作为混音的一部分   过程

...我认为你的意思是:“......在课堂上装饰......”而不是“在作为其论证的阶级”(后者将是一场灾难)。

  

old_style_mix只会更新   例如,类词典   MixedWithOldStyleClass用   mixin类的内容(例如   MixinOldSchoolRemix)字典。

不好 - 例如MixinOldSchoolRemixMixinClass派生的信息在前者的字典中。因此,old_style_mix必须采取不同的策略:例如,构建一个新类(我认为必须是一个新类,因为旧类的接受新的类 - 样式为__bases__),具有适当的基础序列,以及适当调整的词典。

  

这是一个合理的策略吗?

以上附带条件。

  

这似乎很常见   问题,鉴于有很多   可用模块仍在使用   旧式的课程。

...但是混合使用从未设计过类似mixin的类肯定是​​一个常见的设计模式,所以这个问题根本不常见(我不记得看到它了自从新式课程诞生以来的许多年里,我一直在积极咨询,教授高级课程,并在这些年里帮助人们解决Python问题,以及自己做大量的软件开发 - 我确实倾向于遇到了人们可能遇到的任何“相当常见”的问题,这些问题已经存在了足够长的时间! - 。)。

以下是您的类装饰器可以执行的示例代码(如果您希望将其放在类装饰器中而不是直接内联...):

>>> class Mixo(object):
...   def foo(self):
...     print 'Mixo.foo'
...     self.thesuper.foo(self)
... 
>>> class Old:
...   def foo(self):
...     print 'Old.foo'
... 
>>> class Mixed(Mixo, Old):
...   thesuper = Old
... 
>>> m = Mixed()
>>> m.foo()
Mixo.foo
Old.foo

如果您想在装扮器中Mixed的假定名称/绑定下构建Mixo,可以通过调用type或设置{{1}来执行此操作}(其中Mixed.__name__ = cls.__name__是你要装饰的类)。我认为后一种方法更简单(警告,未经测试的代码 - 上面的交互式shell会话是真实的,但我没有测试过以下代码):

cls