Python のクラスメンバ設定には setattr が便利 (かも)
概要
- Python のクラスメンバ設定の方法について調べてみた。
- 引数が増えたときは、dictionary 使った方が良さそう。
- 引数チェックするのにコード増える⇒効率良く書くには――
- setattr うまく使うと楽に書ける!!
サンプル概要
- Pet クラスを作ってみる。メンバは2つ。
- name : ペットの名前 (string)
- category : ペットの種類 (string)
- category ごとの鳴き声を出させる。
(その1) 普通に作る。
- コンストラクタで普通に設定。引数に連ねて書く。
- test.py
class Pet1 : def __init__(self, name, category) : self.name = name self.category = category def bark(self) : if self.category == 'dog' : return "ワンワン" if self.category == 'cat' : return "にゃー" if self.category == 'elephant' : return "パオー" # others return "・・・"
- メモ
- 普通の関数と同様、引数でメンバを設定。
- ○ 一目見て、設定するメンバが分かりやすい。
- × 今後必要なメンバが増えると引数が増える。
(その2) dictionary で設定
- dictionary 型の引数で設定する。エラーチェックも付ける。
- メンバが無ければ「KeyError」を上げる。
- test.py
class Pet2 : def __init__(self, params) : if not 'name' in params : raise KeyError('name') if not 'category' in params : raise KeyError('category') self.name = params['name'] self.category = params['category'] def bark(self) : # 略
- メモ
- ○ 必要なメンバが増えても、引数を増やす必要が無い。
- △ エラーチェックのところ見れば、設定するメンバが分かる。
- × params の中に存在しない値にアクセスしようとすると落ちる。⇒ エラーチェック必須。
- × 引数の項目増えるとエラーチェックのコードが増大する。
(その3) dictionary で設定 + setattr を使用。
- Python の標準関数「setattr」を使用する。
class Pet3 : def __init__(self, params) : keys = ['name', 'category'] for key in keys : if not key in params : raise KeyError(key) setattr(self, key, params[key]) def bark(self) : # 略
- メモ
- ○ 必要なメンバ増えても、引数を増やす必要が無い。
- ○ keys 内に必要なメンバを書き込めば、メンバの追加・変更可能。
- ○ for 文の中でエラーチェックと値の設定行っているので、コード増えない。
- △ 必要なメンバは (その1) の方が見やすいか…?⇒個々人によるかな。
実際に使ってみる。
- それぞれ、同じように利用可能。
- ただし、Pet1 は引数設定、Pet2 と Pet3 は dictionary 型指定。
$ ipython Python 2.7.5 (default, Jun 17 2014, 18:11:42) Type "copyright", "credits" or "license" for more information. ( 中略 ) In [1]: from test import Pet1, Pet2, Pet3 In [2]: p1 = Pet1('Pochi', 'dog') In [3]: print p1.bark() ワンワン In [4]: p2 = Pet2({'name': 'Tama', 'category': 'cat'}) In [5]: print p2.bark() にゃー In [6]: p3 = Pet3({'name': 'はなこ', 'category': 'elephant'}) In [7]: print p3.bark() パオー
まとめ
- 状況に応じて使い分け必要。
- (その1) と (その3) が使えれば、大体は何とかなるか。な?