読者です 読者をやめる 読者になる 読者になる

methaneのブログ

このブログに乗せているサンプルコードはすべてNYSLです。

Pythonにコンストラクタなんて構文は無いし、親クラスを呼び出す構文も無い

Python

http://d.hatena.ne.jp/w_o/20081204#p2

まず…って書こうとしたら追記してあった。superの件に関しては、Pythonの人は、「やりかたはひとつがよい」と言ってるので、複数の書きかたができるPythonは悪であると言えるだろう。

これ、よく誤解されてるけど、「何をするにしてもやり方がひとつ」なんて最初から誰も思ってないから。チューリングマシンだって同じ問題を解くTMを何種類も設計できるし。

Pythonで「やり方がひとつ」というのは、たとえば構文を追加する際「こう書きたい!」っていう意見が出ても、その書き方が既存の書き方に対して明確なアドバンテージが無ければ採用しないとか、そういうの。数タイプ減るだけじゃダメ、2行が1行になるのもダメ、3行が1行になるのは、その3行が頻繁に出るならアリかな。

D言語に似てるのは」とか書かれたので、ちゃんと説明しておくと、昨日の話のコンストラクタについては、僕の中で、評価基準がみっつあって、

* 自分のクラスの名前を書かなくていい
* 親クラスの名前を書かなくていい
* 間違ったらちゃんとエラーになって停止する

の三点、で、重要度として、「ちゃんと止まる >>>> 自分の名前 = 親の名前」というような感じ。

C++は、自分の名前と親の名前がいるけど、ちゃんと止まるので許容範囲内。

Javaは、自分の名前がいるけど、親の名前がいらなくて、ちゃんと止まるので良い。

Dは自分の名前も親の名前もいらないし、ちゃんと止まるので素晴らしい、というような話でした。

で、Rubyはmoduleを使って委譲ができるので、クラスの継承が必要無いのであまり関係無い。

Perlはもうなんでも良い。

Pythonはクラス継承が必要だというのに、自分のクラス名が必要かつ、一貫性が壊れててもわからない、文法が酷い等の理由でF***(FGMT = Fine Grain Multi-Threadingのこと)というような感じでした。

まず「自分のクラス名が必要」って意味が判らない。あと、多重継承できる言語で親クラスを指定せずに親クラスの初期化ができる言語があったらぜひ見せてくれ。それに、継承している段階でプログラマが親クラスを知っていないといけないのに、なんで親クラスを隠蔽する必要があるの?

そもそも、Pythonにクラス名という名前空間は存在しない。クラスはただのtype型オブジェクトであり、 class Foo(object): と書いたときには Foo という変数にそのオブジェクトが代入されているだけ。クラス名は、そのクラスオブジェクトのプロパティとして文字列オブジェクトが入っているだけであり、名前空間は一切汚さない。どうしても super と書きたかったら、superという変数にクラス入れたら良いよ。

suepr = Foo
class Bar(super):
  def __init__(self):
    super.__init__(self)
del super

次に、Pythonにコンストラクタなんて存在しない。classの中の def も、そうでない def と同じくただの関数宣言でしかない(便宜上メソッドと呼ばれるが、宣言の段階では断じてメソッドではない)し、 __init__ というのもただの関数でしかない。

「なんでJava/C#/C++みたいなコンストラクタ無いの?」という質問には、逆に「なんで普通の関数とオブジェクトの範囲内でできることのために、特別な構文、キーワード、システムを導入するの?」と返そう。

Pythonは、ほかの高級言語に対して「特別ルール」が圧倒的に少ないのに、能力が劣っている訳ではない。
特別ルールが多い言語に比べると、少しだけタイプ数が増えるかもしれないけれども、予想外の動作をすることもないし、何かのやり方を忘れて構文を調べなおすことも殆ど無い。

複雑なシステムと沢山の特別ルールとキーワードを覚えておけるくらい記憶力に余力があるなら、Perlでも使ってたら良いよ。