Python での組み込み型をより自然な名前にする

あと10枚ぐらいスライドを減らさないとまずいことになりそうなのに、なぜかPythonネタを投下してみる。

Ruby での String, Array, Hash に相当するのは、Python では str, list, dict になる (小文字であることに注意)。
困ったことに、これらは変数名としても実にポピュラーなので、同名の変数名を定義してしまうとこれらが使えなくなってしまう。

## Python でこうすると、組み込みの str, list, dict が
## shadowing されてしまう
str = "foo"
list = [1, 2, 3]
dict = {"one": 1, "two": 2}

RubyJava ではクラス名は大文字から始まるので、変数名とバッティングすることはほぼない*1。素晴らしい。

string = "foo"       # クラス名 String とバッティングしない
array  = [1, 2, 3]   # クラス名 Array とバッティングしない
hash   = {"one"=>1}  # クラス名 Hash とバッティングしない

さて、Python でのこの問題に対処するには、変数名として str, list, dict などを使わないのが一般的だ。かわりにどんな変数名が使われるかというと・・・

  • str のかわりに S, s, string, (aStr)
  • list のかわりに L, lst, (aList, array)
  • dict のかわりに D, dct, (aDict, hash)

こんなところか。一文字での S, L, D は嫌う人もいそうだが、マニュアルでもよく使われており、決してマイナーな流儀ではない。aStr や aList は Smalltalk 由来の流儀だが、あまり見かけない。array や hash は Ruby 流儀であり、ワシはよく使うが、他の人が使っているのを見たことはない。

まあぶっちゃけ、命名規則としてはどの流儀もよさそうにはみえない。str, list, dict をローカル変数名として使うのが一番自然に思う。Python 3.0 で print を文から関数に変えるぐらいの変更をしているんだから、str, list, dict も Str, List, Dict に改名して欲しかった。

・・・とここまで考えて、だったら自分で改名してやればいいじゃん? ということに気がついた (遅いわ!)。Python には __builtins__ という組み込みパッケージがあり*2、これに Str や List や Dict を追加してやればいいだけだ。

### __builtins__ にエイリアスを追加
>>> __builtins__.Str     = str
>>> __builtins__.List    = list
>>> __builtins__.Dict    = dict
>>> __builtins__.Tuple   = tuple
>>> __builtins__.Set     = set
>>> __builtins__.Object  = object 
>>> __builtins__.Type    = type
>>> __builtins__.Int     = int 
>>> __builtins__.Long    = long
>>> __builtins__.Float   = float
>>> __builtins__.Complex = complex
>>> __builtins__.Bool    = bool
>>> __builtins__.Unicode = unicode
>>> __builtins__.File    = file 

こうすれば、str や list や dict という変数名を使っても問題ない。

### __builtins__ に追加したので、どこでも使えるようになる。
>>> print Str, List, Dict
<type 'str'> <type 'list'> <type 'dict'>

### str や list や dict という変数名を使っても無問題。ブラボー!
>>> str = "foo"
>>> print type(str) == Str
True
>>> list = [1, 2, 3]
>>> print type(list) == List
True

### また大文字から始まるので、クラス名としても自然である。ブラボー!
>>> dict = Dict([("one", 1), ("two", 2)])
>>> print dict
{'two': 2, 'one': 1}

やー、もう、鼻血がでるほどうれしいね。


追記(2009-07-16): 初心者はマネしないように。やるならわかったうえでやってね。

*1:ただし、Javaではローカル変数名とインスタンス変数名がバッティングしやすい。

*2:Ruby でいうところの Kernl モジュールに相当。