LoginSignup
10
10

More than 5 years have passed since last update.

DDDのリポジトリパターンとコンテキストマップを利用するにあたって、インスタンスに対して動的に振る舞いを付与したくなったので、Python で DCI (Data Context Interaction) を実現する方法について調べてみました。

Roles パッケージを使う

DCI in Pythonスレから産まれたらしい Python の DCI パッケージ

わりと古くて人気もなさそうだけど、よくできている。

class Person(object):
    def __init__(self, name):
        self.name = name


from roles import RoleType
class Carpenter(object):
    __metaclass__ = RoleType
    def chop(self):
          return "chop, chop"

のように Person, Carpenter を定義すると、

>>> person = Person("John")
>>> Carpenter(person)
<Person+Carpenter object at 0x...>

Person インスタンスに Carpenter の振る舞いを付与できる。

Dynamic Mixin

Mixin クラスの属性をインスタンスに動的に追加する関数を実装。

import types

def mixin(instance, mixin_class):
    """Dynamic mixin of methods into instance - works only for new style classes"""
    for name in mixin_class.__dict__:
        if name.startswith('__') and name.endswith('__') \
        or not  type(mixin_class.__dict__[name])==types.FunctionType:
            continue

        instance.__dict__[name]=mixin_class.__dict__[name].__get__(instance)

使い方

class Person(object):
    def __init__(self, name):
        self.name = name

class CarpenterMixin(object):
    def chop(self):
          return "chop, chop"

と定義されていたとして、

>>> person = Person("John")
>>> mixin(person, CarpenterMixin)
>>> person.chop()
    'chop, chop'

わりと手軽。

Dynamic Mixin (2)

instance のクラスの継承ツリーを動的に書き換えるアグレッシブな方法。
説明は省略。リンク先を見てください。

その他

インスタンスそのものに振る舞いを付与するのを諦めて、Delegation で実現するのもありかと思います。

参考情報

以下のページを大いに参考にさせて頂きました。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10