2系から3系への変換ツール (2to3) | Python-izm

2系から3系への変換ツール

Pythonでは2系のソースコードを3系へ変換する2to3というツールがあります。変換時の差分を出力したり、ファイル出力することもできるので、バージョン移行時における活用や、2系のソースコードが3系ではどのような形になるのかを確認することもできます。

実行準備

2to3は、2系3系ともに最新のバージョンであれば標準で付属しています。Windows以外では2to3というコマンドがすぐに使えるため、下記コマンドを試してみてください。コンソールにヘルプが表示されれば利用可能な状態です。

2to3 --help

Windowsの場合は<PythonInstallDir>¥Tools¥Scripts2to3.pyが配置されているので、たとえばPythonがC:¥Python27へインストールされている場合は次のように実行します。

python C:¥Python27¥Tools¥Scripts¥2to3.py --help

コマンドが長くなるため、本項では2to3コマンドで記載していきます。たとえば下記コマンドの場合、Windowsで実行する場合は該当する部分を置き換えて実行してください。
(Windows以外はそのまま実行)

2to3 --help

(Windowsの場合は2to3の部分をpython C:¥Python27¥Tools¥Scripts¥2to3.pyへ置き換える)

python C:\Python27\Tools\Scripts\2to3.py --help

また次のソースコードを動作確認として使用します。これはPython2系で動作するスクリプトで、ファイル名はv2_script.pyとします。

# -*- coding: utf-8 -*- 

import urllib2


url = "https://www.python-izm.com/"

htmldata = urllib2.urlopen(url)
htmldata.close()

for i in xrange(3):
    print u'2to3のテスト'

s = raw_input()
print s

差分を出力する

差分を出力する場合は、単純にファイル名を指定します。元のファイルには何も影響を与えないので、特にバックアップなどを取っておく必要はありません。

2to3 v2_script.py

実行結果

RefactoringTool: Skipping optional fixer: buffer
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: set_literal
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored v2_script.py
--- v2_script.py        (original)
+++ v2_script.py        (refactored)
@@ -11,5 +11,5 @@
 for i in range(3):
     print('2to3のテスト')

-s = input()
+s = eval(input())
 print(s)
RefactoringTool: Files that were modified:
RefactoringTool: v2_script.py

上記のように、変換を実施した場合に削除されるコード、追加されるコードが出力されます。たとえばPython 3系ではxrangerangeへ統一されたためrangeへ変換、printは関数化されたためカッコでくくる、u”は必要ないので削除、raw_inputinputへ変換されるのがわかります。ただし本来であればパッケージが再編されたurllib2も差分として出力されてもいいはずですが、ここでは出力されません。そのためあくまでも参考程度にとどめておくのが良いかもしれません。

ファイル出力する

ファイルへ出力を行う場合はwオプションを使用します。

2to3 -w v2_script.py

実行後は次のように2つのファイルが出力されます。

  • v2_script.py
  • v2_script.py.bak

v2_script.pyは変換後のファイルです。xrangerangeへ、raw_inputinputへ変換されたファイルになります。v2_script.py.bakはバックアップファイルです。変換前のファイルがそのまま.bakを付与されて残ります。

ここで変換前後のファイルを比較してみましょう。

# -*- coding: utf-8 -*- 

import urllib2


url = "https://www.python-izm.com/"

htmldata = urllib2.urlopen(url)
htmldata.close()

for i in xrange(3):
    print u'2to3のテスト'

s = raw_input()
print s
# -*- coding: utf-8 -*- 

import urllib.request, urllib.error, urllib.parse


url = "https://www.python-izm.com/"

htmldata = urllib.request.urlopen(url)
htmldata.close()

for i in range(3):
    print('2to3のテスト')

s = input()
print(s)

変換後のスクリプトを3系のインタープリタで実行しても、もちろんきちんと動作します。3系への移行を考えている方も、2系からどういった点が変わったのかを把握することができるので、そうった点でもおすすめです。なおバックアップファイルが必要ない場合はnオプションを付与することで、変換後のファイルのみ出力されます。

2to3 -w -n v2_script.py