2007-08-05

最近クラスを使うことが減ってきている自分

なぜオブジェクト指向は嫌われているのか?

上の記事を見て、ふと思ったんだが最近自分はクラスを嫌っている。

GOFを勉強したてのころは喜々としてVisitorパターンなどを使って、後になって、「メチャクチャ読みにくいな、このプログラム」などと思ったことがあった。

こないだ仕事でWorkerThreadを作った時は、サーバーとワーカーの二つだけをクラスにした。が、その他本来JAVAならコマンドパターンを使う部分では、関数を引数に渡すので、クラスを使う必要はまったくなかった。むしろPythonの場合、そうしないほうが柔軟な気もする。

で、ちょっと気になったので、TurboGearsやPylonsや他のチュートリアルを見ながら作った標準的なプログラムたちと、自分が0から書いたプログラムの中での、クラス/関数のカウントをしてみた。

まず、標準的なものでのカウント。

ayu@~/work% ./cfcount.py BlogTutorial BlogTutorial2 wsgitutorial 
Class total: 54
Function total: 19
Class rate: 0.739726027397

次に自分のスクリプトでのカウント。(自分が公開している、mword, cmecab, clitter, extbodyでの集計)
ayu@~/work% ./cfcount.py dev_pub                                
Class total: 4
Function total: 55
Class rate: 0.0677966101695

これを見ると、結果は明らかに自分がクラスを書くことが少ない。
標準的なほうは、「フレームワークに従わねばならない」という事情があるからしかたないにしても自分はあまりにも書かなすぎではないだろうか。

これは普通の傾向だろうか。他のPythonistaのみなさんもこんなものなんだろうか。

ちなみにカウントに使ったプログラムはこれ。
(このプログラムもクラスなど使わない。もしこれをJAVAで書くなら"class XXCounter{...}"とか書かなきゃならないんだよね。。。)
#!/usr/bin/python
# _*_ coding: utf-8 _*_
import os
import re
from itertools import chain

def class_and_func_enumerator(fname):
fp = file(fname)
for line in fp:
m = re.match("^(def|class) ", line)
if m: yield m.group(1)
fp.close()

def count_in_directory(directory):
for dpath, dnames, fnames in os.walk(directory):
for fname in fnames:
if fname.endswith(".py"):
yield class_and_func_enumerator(dpath + os.sep + fname)

def count_all(directories):
counter = {"def": 0, "class": 0}
for directory in directories:
for label in chain(*list(count_in_directory(directory))):
counter[label] += 1

print "Class total:", counter["class"]
print "Function total:", counter["def"]

total = float(sum(counter.values()))
if total != 0:
print "Class rate:", counter["class"] / total

def main():
import optparse

parser = optparse.OptionParser(u"""
Usage:
cfcount.py dir1 [dir2 dir3 ...]

指定したディレクトリ以下にある*.pyファイルのクラス、関数を数えます。
""")

(options, args) = parser.parse_args()

count_all(args)

if __name__ == "__main__":
main()