C 言語の関数内ローカルな static、のようなことを Python でやりたいとしたら

C/C++ の static は役割過多なので説明が冗長になってやだ…。

他愛もないちゃぁ他愛もないんだけれど、ちょっと大きめのプロジェクトをやりかけで、こんなニーズが出てきた:

  1. class でなくモジュールレベル関数で十分な機能があるとして。
  2. 何度も呼び出される際に少しばかりコストが気になるものがあるとして。
  3. であればモジュールレベル変数で良いのか?
  4. けどさそれって実装の詳細であって曝したくはないぞ

C/C++ で、まぁ「マルチスレッドではオススメ出来ないけれど(というか原則 NG)」な、だけれども時折というかしょっちゅう便利な static:

1 int myfun()
2 {
3     static int initialized = 0;
4     if (!initialized) {
5         /* 何か初期化処理 */
6         initialized = 1;
7     }
8     return 0;
9 }

これね。

Python だと結局 global のお世話になるしかないよね:

1 def spawn(cmd, verbose=0, dry_run=False):
2     global _SOME_RE  # semantically I mean this is like 'static' of C-language.
3     try:
4         _SOME_RE  # nop
5     except NameError:
6         _SOME_RE = re.compile(..., flags=re.I)

まぁここまでやったって、結局ダイナミックな Python だと _SOME_RE の存在は隠せないんだけれどもね。けどソースコードの可読性は、シンプルに名前(つまりアンダースコア始まり)でプライベートであることを主張するよりは、インデントレベルがトップレベルに現れていないんで、意図が伝わりやすいとは思う。(というか「ローカルのつもりなのに名前衝突についての注意はモジュールレベルで考えなければならない、てのがイケてはいないけれど、まぁそれは受け入れるしかなかろう。)

どうだろなぁ、普段使いのつもりならバッドノウハウだろうなぁ。その「気になるコスト」の度合いと、プライベートっぷりの程度によるだろうね。というかそのモジュール全体の大きさによると思う。大きな機能を任されているモジュールはどうしてもこの手のモジュール変数がたくさん必要になりがちなので、どうしても可読性が落ちるのね。