Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

実装モジュールを切り替える

pythonの定番パターンだと思うんだけどあんまり書いてなさげなので書いておく。
twisted厨にはおなじみのコードなのでtwisted厨はよまなくて良し!!
実装を抽象化しておき、モジュール切り替え + シングルトン化で使用する側は実装
を意識しないでよくする例。
抽象化なのでABCMetaを使用。

example/core/base.py

from abc import ABCMeta, abstractmethod

class Base(object):
    
    __metaclass__ = ABCMeta

    @abstractmethod
    def method(self):
        pass

    @classmethod
    def install(cls):
        obj = cls()
        _install(obj)

def _install(engine):
    import core
    import sys
    if sys.modules.get('core.engine', None):
        del sys.modules['core.engine']
    core.engine = engine
    sys.modules['core.engine'] = engine

抽象クラスを定義する。

実装クラス1

example/core/engine1.py

import base

class Engine(base.Base):

    def method(self):
        print("call engine1 method")

実装クラス2

example/core/engine2.py

import base

class Engine(base.Base):

    def method(self):
        print("call engine2 method")

実装を決定するモジュール。
インストーラ

example/core/engine.py

def install():
    try:
        from core import engine1
        print("engine1 install")
        return engine1.Engine.install()
    except ImportError:
        pass
    
    try:
        from core import engine2
        print("engine2 install")
        return engine2.Engine.install()
    except:
        pass

install()

engine1が使える場合には、engine1を、そうでなければengine2を使用する。

で実際に使用する側のコード

example/test.py

from core import engine

engine.method()

pythonではシングルトンをモジュール実現できるので楽だよね。
もっと変態的なモジュールシステムの使い方を知りたい人はMakoのソースとか
読むといいかも知れない。