まずは駆け足に
かれこれ半年(のうち3か月くらい)ほど、Python/Djangoで実戦をしていたので、しばらくは色々と書き残して行こうかと。
第一言語はJavaなので、ややこしいところとかJavaでこうしたかったときに、Pythonではこうするといった感じで書いていきます。
Pythonの型
まずは型です。
Pythonでは、スクリプト言語なんだから型なんて無いんだろうと思われそうですが、実はちゃんと存在しています。たとえばファイルにデータを書き出す時には、整数型は文字列型への変換が必要です。
number = 1 # これで文字列に変換 string_data = str(number) # 今度は整数型に戻した number_data = int(string_data)
こんな感じになります。intだけではなくて、longやfloatも存在します。
Pythonでは、variant型ではないので型変換が必要です。
標準ライブラリを使用する場合にも、これが必要になってくるので忘れないようにしてください。
Unicode型?
Pythonの文字列は、Unicodeです。
実はここが罠で、Unicodeであって、UTF-8などのエンコードとは異なっています。
Unicode は Python の中では、文字コード表だと思ってください。
UnicodeとUTF-8が一緒だとハマる。間違いなく。
どういうことかと言うと
Pythonのソースファイル(UTF-8)を読み込む時に、UTF-8の文字列をUnicode型に変換します。
message = u'これがUnicode型になる'
Pythonのスクリプトファイルは先頭行にファイルの文字コードを指定することが推奨されていますが、こんなところが理由になってくるようです。Javaの場合は、コンパイル時にファイルのエンコードを指定していますよね。それが普段はコンパイルせずに実行するPythonだとファイル側に書くようになっただけのことです。(たぶんね。。。)
で、このことを理解していないうちは、String#encode や String#decodeの意味がわからなかったのですが、これはこういうこと。
UTF-8やShift_JISのString型をdecodeするとUnicode型になる。
Unicode型をencodeすると UTF-8やShift_JISのString型になる。
つまり、Pythonの中では、UTF-8の文字列とUnicodeの文字列は別物。
なんでこんなことになっているのか。。。
Javaでは、StreamWriter/StreamReaderのレベルでの文字コード指定ができます。
しかしPythonでは、もっとジェネリックな低レベルのストリームしか標準ライブラリに存在していないため、文字列側で特に頑張る必要があります。
もちろん、Javaでもプログラムの内部で文字コードを変換することはできます。しかし、結果として取得できるのは、byte配列。でも、PythonはUnicodeから変換した文字列は全てがStringとなってしまう。ここが非常に扱いにくいところでした。パッと見わからないんだもの。
言語レベルの優劣はわからないけど、現時点でプログラムというかシステムを作ろうとしたときに文字列の扱いについて優れているのはJavaだと思いました。正直Javaってどんくさい言語だなぁ、と思うんですが、IO系のアーキテクチャは優れていると感じた。いまさらですけど。。。