0

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

class MixedClass(MixinClass, BaseClass):
    pass

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

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

@old_style_mix(MixinOldSchoolRemix)
class MixedWithOldStyleClass(OldStyleClass)

whereMixinOldSchoolRemix派生自MixinClass并且只是重新实现super用于代替使用包含与其混合的类的类变量的方法,在这种情况下OldStyleClass。此类变量将old_style_mix作为混合过程的一部分设置。

old_style_mix只会MixedWithOldStyleClass用 mixin 类 (eg MixinOldSchoolRemix) 字典的内容更新 eg 的类字典。

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

4

1 回答 1

1

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

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

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

不好——例如,MixinOldSchoolRemix源自的信息不在前者的字典中。因此,必须采取不同的策略:例如,使用适当的碱基序列构建一个新类(我认为它必须是新式的,因为旧式的接受新式的 as ),如以及经过适当调整的字典。MixinClassold_style_mix__bases__

这是一个合理的策略吗?

有了上述条件。

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

...但是带有从未设计为采用 mixins 的类的 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

如果你想在你的装饰器Mixed中使用假定的名称/绑定来构建Mixo,你可以通过调用来完成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
于 2010-09-01T03:35:40.040 回答