Blank File

LinuxとかPythonとかVimとか、趣味でいじる感じで

Python2.7のコードをPython3系用に修正してみた

非常に今さらながら、Python3.4が何とか使えそうになったので、Python2.7から3系へのコード移植を試してみました。自分のコードで修正が必要だった部分を書き残しておきます。たまたま私が引っかかった部分だけなので、2系と3系の違いを網羅するような内容ではありません。その点ご了承ください。

正直、凝ったことをしていなければprint文とパッケージの対応状況に気をつけるだけで何とかなるだろうと慢心してました。実際やってみると想像以上に引っかかるポイントが細々とありました。とはいえ大掛かりな修正を要求されることはなく、基本的に記述を少し修正すれば対応できるものばかりでした。

Print文廃止

これは事前に意識して対応済みでした。

× print 'こんにちは'print('こんにちは')
○ print(u'こんにちは')  #3.3以上はこれでもOK

文字列型 (unicord, str, byte)

u'あいう'など以外にも色々ひっかかりました。 unicodeencodeを使っている箇所があってエラーになりましたが、3系では元からunicodeのはずなのでエンコード処理を消すだけで対応できました。

また、python2.7ではstrとunicode文字列の共通のクラスとしてbasestringがありましたが、文字列はstrに統一されたのでbasestringはなくなりました。isinstance(a, basestring)などと書いていた箇所はisinstance(a, str)に書き換えるだけで期待する動作をしてくれました。

文字列内での変数展開

%を使う記法がなくなりました。これは事前に対応済み。

   x = 3
× 'x = %d' % x
○ 'x = {0}'.format(x)
○ 'x = {0:d}'.format(x)  #型を指定したい場合

相対import

とりあえず1ファイルで作り始めて途中から複数のファイルに分けたような時に__init__.pyを置かないことが多々あったのですが、3系ではこのあたりきちんとしないとimportできませんでした。 とりあえず__init__.pyを追加してインポートできるようにしました。

Generator

2系ではジェネレータgenに対してgen.next()で値を取得できましたが、3系ではこの書き方はサポートされていないそうです。同等のコードはnext(gen)です。こっちのほうがlen()などとも同じ形式でPythonらしいのでしょうか。

StandardError廃止

気に入っていたのですがなくなってしまいました。3系ではExceptionが同等の例外だそうです。

commandsモジュール削除

シェルにコマンドを送ってその出力を取得してくれるモジュールでした。

import commnads

cmd = 'ls'
result = commands.getoutput(cmd)

手軽で気に入っていたのですがなくなってしました。 代替としてosモジュールのpopenを使うそうです。

import os

cmd = 'ls'
result = os.popen(cmd).read()

確かにこっちの方がわかりやすい気もします。

今回は使っていませんでしたが、標準モジュールだとurllibいくつか名称などが変わっているようです。

いまさらpython3を触ってみて

本当に少し触っただけですが、python2.7との違いは細かい部分でそれなりにあるものの、使うだけであれば移行作業はそれほど大変ではないと感じました。

これから細々とした仕様の違いを体感しそうですが、徐々にpython3に移していこうと思います。

むしろその前にしっかり2と3の違いを確認しておくべきですね。今回は完全に思いつきの見切り発車でした。