PythonのMixinの詳細


いくつかの雑談:
Mixinは設計モデル、設計思想である.
特定のclassや関数ではありません.
JavaのMixinはinterfaceと言います
ルビーのMixinはModule
[2]メリット:
1.mixinデザイン迷走クラスの内容を修正しない前提の下で、クラスの機能を拡張する(親を追加する)2.より便利な組織とメンテナンスの異なる構築3.開発の必要に応じて任意に機能を調整することができる4.より多くのクラスを生成することを避けることができる
欠点:継承関係によって制限され、2つの階層の継承のみが推奨されます.
#-------------------------------------------------
ケース1[3]:
class Role:
    def walk(self):
       print(' ')

#---------------------------------------------------------------
class RunMixin:
    def run(self):
       print(' ')

class PromptSkillMixin:
    def use_prompt_skill(self):
       print('         ')

class WalkExMixin:#  Role    ,         ,Role     
    def walk(self):
       print('  ')

class RoleEx(WalkExMixin, PromptSkillMixin, RunMixin, Role):

    def marco(self):
       return [self.run, self.use_prompt_skill]

    def use_marco(self):
        print("---------------use_marco  ----------------")
        for action in self.marco():
            action()
        print("--------use_marco  ----------")
if __name__ == '__main__':
    r = RoleEx()

    r.use_marco()
    r.walk()
実験結果:
---------------use_marcoテクノロジー----------走りは瞬発スキルを使用しています---------use_marco終了--------------疾走
 
このケースの明らかなメリットは、
ロールを修正することなく多くの機能を拡張しました
ある时、Roleこれはあなたの同僚が开発したので、あなたは修正する権限がなくて、あなたの同僚はあなたにインタフェースを呼び出す権限だけをあげました.
あるいは、免責と安定のために、例えばその時に問題が発生したら、誰が鍋を背負っているのか、あなたは会社に元のコードを修正することを許可されません.
#------------------------------------------------
ケース2[1]:
class Displayer():
    def display(self, message):
        print("--------②   Displayer.display  ---start-----")
        print("Displayer self=",self)
        print(message)
        print("--------②   Displayer.display  ---end-----
") class LoggerMixin(): def log(self, message, filename='logfile.txt'): print("MySubClass self=",self) with open(filename, 'a') as fh: print("--------③ LoggerMixin.log ---start-----") fh.write(message) print("--------③ LoggerMixin.log ---end-----
") def display(self, message): print("display self=",self)# self MySubClass, LoggerMixin print("------① LoggerMixin display -start--
") super().display(message)# Displayer.display() self.log(message) print("------① LoggerMixin display -end--
") class MySubClass(LoggerMixin, Displayer): def log(self, message): super().log(message, filename='subclasslog.txt') subclass = MySubClass() subclass.display("This string will be shown and logged in subclasslog.txt") ''' 1. MySubClass.display() is resolved to LoggerMixin.display(). MySubClass.display() LoggerMixin.display() 。 。 MySubClass , ,LoggerMixin Displayer ,LoggerMixin , display() 。 2. LoggerMixin.display() calls super().display(), which is resolved to Displayer.display(). LoggerMixin.display() super().display(), , MySubClass , Displayer display() 。 。 , LoggerMixin.display() super().display() , 。 ? LoggerMixin , MySubClass 。MySubClass LoggerMixin, Displayer。 , Displayer display() 。 3. It alse calls self.log(). Since self, in this case, is a MySubClass instance, it resolves to MySubClass.log(). MySubClass.log() calls super().log(), which is resolved back to LoggerMixin.log(). , LoggerMixin self.log() 。 LoggerMixin log , 。 LoggerMixin display() self, MySubClass , MySubClass , log , log , MySubClass.log() , LoggerMixin.log() 。 MySubClass.log() super().log() , , LoggerMixin log() 。
この例はネット上でとても有名で、[1]でこの例の詳細を分析して、詳細は私はすでに上のコードにコピーしました.
核心思想と目標は(個人分析):
LoggerMixinがなければ、このコードにはDisplayerが残っているので、全体のコードの目標は:
Displayerを修正しない場合(これは非常に重要)、Displayerの機能を拡張する.
#-------------ケース2[1]実験結果−感性分析---------------------------------
実験結果は以下の通りである.
displayのself=<_main__.mysubclass object=""at="">----①ここではLoggerMixinのdisplay関数-start--
-------②ここではDisplayer.display関数---start-----Displayerのself=<_main__.mysubclass object=""at=">>This string will be shown and logged in subclasslog.txt------②ここではDisplayer.display関数---end------
MySubClass self= <__main__.mysubclass object=""at="">----③ここでLoggerMixin.log関数---start-----③ここでLoggerMixin.log関数---end------
-----1ここではLoggerMixinのdisplay関数-end--
私たちは直感的に見ることができます.
LoggerMixinがなければ、上記の結果は赤い部分しか残っていませんが、
現在の実験結果の黒い部分は従来のDisplayerのクラスの機能を拡張したものである.
また、Displayerのクラスが変更されないことを確認します.
#-----------------------------
個人総括MIXINの役割:
親を変更しない場合は、親の機能を拡張および削除します.
どうして「検査」がないのですか.データベースのような添削改査
遺産項目では、同僚からのインタフェースが「メンバー変数の照会と取得」機能を実現しているに違いない.MIXINがなくても「調査」機能を備えている.
増幅:上記の2つの例はいずれも機能を増加させる作用を体現している.
削除:上の例1を参照すると、WalkExMixinのWalk関数は元の親ロールのWalk関数をブロックします.
だから、MIXINというデザインモデルが現れた目的は:
元の親に対して機能上の拡張和(削除)を実現することができる.
#----------------------------------------
Reference:
[1]一例Pythonに近づくMixin類:Pythonが多く受け継いだ魔力を利用する
[2]オブジェクト-mixin設計モードへの適用(マルチ継承適用シーン)
[3]python_Mixin設計モード