クラスの動的拡張

30分プログラム、その169。Pythonで動的にクラスにメソッドを追加してみる。
Pythonでfoo.xとしたとき、

  • インスタンスfooからxを探す
  • 見付からなかったらfooのクラスからxを探す
  • 見付からなかったらfooのクラスの親クラスからxを探す

という風に継承ツリーをどんどんさかのぼっていくので、単純にクラスに関数してやればメソッドを追加できる。

class Hoge:
  pass

# メソッドの追加
Hoge.id = (lambda self,n: n)

本当はこれでlistクラスにいろいろ追加して、PythonのリストをRubyっぽく、ということがやりたかったのだけれども、「ビルドインクラスは拡張できません」と怒られら。

def f(self):
    return len(self)

# listはビルドインクラスなので拡張できない
list.size = f

使い方

試しに動的にカウンタを定義した。

c = Counter()

print c.value # => 0

c.inc()
c.inc()
print c.value # => 2

c.dec()
print c.value # => 1

ソースコード

#! /usr/bin/python
# -*- mode:python; coding:utf-8 -*-
#
# dynamic.py -
#
# Copyright(C) 2007 by mzp
# Author: MIZUNO Hiroki <hiroki1124@gmail.com> 
# http://mzp.sakura.ne.jp/
#
# Timestamp: 2007/10/30 23:06:17
#
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Python itself.
#

class Counter:
    pass

def init(self):
    self.value = 0
Counter.__init__ = init

def inc(self):
    self.value += 1

Counter.inc = inc

def dec(self):
    self.value -= 1
Counter.dec = dec

if __name__ == '__main__':
    c = Counter()
    c.inc()
    c.inc()
    print c.value

    c.dec()
    print c.value