Hatena::Grouppython

nelnal@python

2008-02-25

[][] __metaclass__ ではまる 17:24  __metaclass__ ではまる - nelnal@python を含むブックマーク はてなブックマーク -  __metaclass__ ではまる - nelnal@python

前回書いた Singleton クラスを使用してプログラムを書いていたら TypeError がどうしても出てしまいはまった。

要因1 : Singleton クラスの記述ミス

class Test:
    __metaclass__ = Singleton
    
    # (途中は省略)

    def __init__( self, **kwargs ):
        # (実際に記述はあるが省略)

    # (以下も省略)

エラー内容

TypeError: __call__() got an unexpected keyword argument 'xxxx'

そこで __metaclass__ のことについて調べたり、エラーコードをそのまま検索に掛けたりとした。



結局のところ原因は Singleton クラスの __init__, __call__ の両メソッドの引数に原因があった。

class Singleton( type ):
    def __init__( self, *args, **kwargs ):
        type.__init__( self, *args, **kwargs )
        self._instance = None

    def __call__( self, *args, **kwargs ):
        if self._instance is None:
            self._instance = type.__call__( self, *args, **kwargs )
        return self._instance

というわけで、上記の kwargs が無かったことで、

元の Test クラスではキーワード引数が使えない様になっていたことが原因だった模様。


要因2 : インタラクティブシェルの reload() 動作

もう一つのはまった要因として reload の動作がある。


まず、モジュール A を import したとする。

import A

モジュール A は内部で自作したモジュール B を import している。


モジュールA

import B

もし、モジュール A のテスト中にモジュール B の障害を発見し、これを修正したとする。


ここで

>>> reload( A )

としてもモジュール A 内部で import されているモジュール B の変更は取り込まれない(!!)


この場合は

>>> reload( B )

とすることでモジュール B の変更が取り込まれる。


[] コンストラクタ・デストラクタ 11:01  コンストラクタ・デストラクタ - nelnal@python を含むブックマーク はてなブックマーク -  コンストラクタ・デストラクタ - nelnal@python

Python でのコンストラクタとデストラクタの書き方について

class Test( Base ):
    def __init__( self ): # コンストラクタ
        Base.__init__( self )

    def __del__( self ): # デストラクタ
        Base.__del__( self )

デストラクタの実行タイミングについては

Pythonのガベージコレクションに任せることになる為、不明。


明確なタイミングで終了処理などしたい場合は終了処理を実行するメソッドを用意して、

明示的に使用したほうが良い。

Version 2.5 以上であれば、with ステートメントを使用すれば良い。

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080225