【问题标题】:How to apply a "mixin" class to an old-style base class如何将“mixin”类应用于旧式基类
【发布时间】:2010-09-01 03:18:53
【问题描述】:

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

class MixedClass(MixinClass, BaseClass):
    pass

将此 mixin 应用于旧式类的最流畅的方法是什么?它在其__init__ 方法中使用对super 的调用,因此这可能(?)必须更改,但否则我想对MixinClass 进行尽可能少的更改。我应该能够派生一个进行必要更改的子类。

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

@old_style_mix(MixinOldSchoolRemix)
class MixedWithOldStyleClass(OldStyleClass)

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

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

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

【问题讨论】:

  • 我建议将旧样式类转换为新样式类会不会过分?
  • @aaronasterling:如果我可以让它在标准库的所有安装中进行追溯更新,我肯定会这样做。

标签: python inheritance mixins


【解决方案1】:

这个类变量将由 old_style_mix 作为混音的一部分 过程。

...我假设您的意思是:“...在它正在装饰的班级...”而不是“在作为其论点的班级上”(后者将是一场灾难)。

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

不好 -- 例如,MixinOldSchoolRemix 派生自 MixinClass 的信息在前者的字典中不是。所以,old_style_mix 必须采取不同的策略:例如,构建一个新类(我认为它必须是新类,因为旧类接受新类as __bases__) 具有适当的碱基序列,以及经过适当调整的字典。

这是一个合理的策略吗?

具备上述条件。

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

...但是带有从未设计为采用 mixin 的类的 mixins 绝对 不是 一种常见的设计模式,所以这个问题根本不常见(我什至不记得见过它)新式课程诞生后的很多年里,我都在积极咨询,教授高级课程,帮助解决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

如果你想在你的装饰器中使用Mixo 的假定名称/绑定来构建Mixed,你可以调用type,或者设置Mixed.__name__ = cls.__name__(其中cls 是你正在装饰的班级)。我认为后一种方法更简单(警告,未经测试的代码——上面的交互式 shell 会话是真实的,但我没有测试过以下代码):

def oldstylemix(mixin):
    def makemix(cls):
        class Mixed(mixin, cls):
            thesuper = cls
        Mixed.__name__ = cls.__name__
        return Mixed
    return makemix

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多