[Python] メソッドを一時的に変更する方法とその実例

環境

この記事の内容は、Python 2.4.4c1, Twisted 2.4.0-1で確認しました。

メソッドを一時的に変更する方法

>>> class Foo(object):
...     def bar(self):
...         print "bar"
...     def baz(self):
...         print "baz"
... 

上のように定義されるクラスがあるとします。

このクラスをインスタンス化し、barメソッドを呼び出せば、当然"bar"が表示されます。

>>> f = Foo()
>>> f.bar()
bar

ところで、baz属性をbar属性に代入してみます。そうすると、barメソッドを呼び出せば、実体はbazメソッドですから、"baz"が表示されます。

>>> f.bar = f.baz
>>> f.bar()
baz

ここで、del文によってbar属性を削除すると、元のbarメソッドを呼び出すことができるようになります。

>>> del f.bar
>>> f.bar()
bar

このテクニックの実例

このテクニックは、Twistedのtwisted.internet.tcp.BaseClientクラスで使用されています。このクラスはファイルディスクリプタで、select.select関数の結果に応じて、doReadメソッドかdoWriteメソッドが呼び出されます。しかし、ネットワーククライアントなので、実際に読み書きする前に接続する必要があります。そこでこのクラスでは、コンストラクタ(の最後に実行されるメソッド)で、

            self.doWrite = self.doConnect
            self.doRead = self.doConnect

のようにして、doWriteメソッドとdoReadメソッドをdoConnectメソッドに置き換えています。そして、最初に読み書きするときは、doWriteメソッドやdoReadメソッドの代わりにdoConnectメソッドを呼び出させておいて、接続が完了したら、doConnectメソッドの最後で、

        del self.doWrite
        del self.doRead

として、メソッドを元に戻しています。