背景
ずっとpython3を使っていたが、新しく入った開発で、python2で開発されていることしり、自分は3で書いてしまったが、最終的には、2に統一が必要となったので、調べた。
3to2をインストール
- https://pypi.python.org/pypi/3to2 から、zipをダウンロードする
- zipをあけ、
cd 3to2-x.x.x
python setup.py install
3to2を試す
ターミナルで以下のコマンドを打つと、Optionを確認できる
3to2 --help
Usage: 3to2 [options] file|dir ...
Options:
-h, --help show this help message and exit
-d, --doctests_only Fix up doctests only
-f FIX, --fix=FIX Each FIX specifies a transformation; default: all
-j PROCESSES, --processes=PROCESSES
Run 3to2 concurrently
-x NOFIX, --nofix=NOFIX
Prevent a fixer from being run.
-l, --list-fixes List available transformations (fixes/fix_*.py)
-v, --verbose More verbose logging
-w, --write Write back modified files
-n, --nobackups Don't write backups for modified files.
--no-diffs Don't show diffs of the refactoring
とりあえず、(Branchを切って、)直接 -w
を使って書き込むことにする。そうでないと、ただ、3から2に変更する部分だけが表示されて終わる。
3to2 -w aaaa.py
を実行して、成功!
その他
ただ、これだけではまだエラーが出る可能性がある。
1. 文字コード関係
SyntaxError: Non-ASCII character '\xe6' in file aaaa.py on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
この場合は、URLないの支持に従い# coding=<encoding name>
を一行目に書く。
Encoding nameの部分には、utf-8
とか書けばいい
2. 全てのStringの前に、u
がついて、エラーの原因となる
TypeError: "delimiter" must be string, not unicode
例えば、pandasのdataframeを変換すると:
変換前(python3)
df.to_csv('aaa.tsv', sep='\t')
変換後(python2)
df.to_csv(u'aaa.tsv', sep=u'\t')
となり、TypeError: "delimiter" must be string, not unicode
と言われるので、
sep='\t'の前のu
を取り除く
3. 同じくto_csv
部分でなぞのエラーが出る
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
Python2では、csvで、unicodeに対応していないらしいので、
encoding='utf-8'
を追加して、
df.to_csv('aaa.tsv', sep='\t', encoding='utf-8')
とすれば解決する
4. cld2がインストールできなくなった
python 2.7.6にしてから、
pip intall cld2
が、失敗し、No package 'libffi' found
というエラーが出る
macの場合は、
brew install libffi
でインストールする。→成功
Ubuntuの場合はやってないので不確かですが、apt-get install libffi
とかlibffi-dev
でいいのか。。?
5. Unicode関係のなぞのエラー2
TypeError: initializer for ctype 'char *' must be a str or list or tuple, not unicode
上のcld2に渡しているものが、unicodeだったので、以下のように変更
変更前
reliable, _, lang = cld2.detect(name)
変更後
reliable, _, lang = cld2.detect(name.encode('utf-8'))
エラーからの結論
Python2は、Unicodeで出るエラーがおおいので、気をつける!
おまけ
バージョン管理
Python2と3を両方使うことがある人は、pyenv
というのを使って、Localでわけて使うことが便利だと考えられる。
持ってるバージョンを確かめる
pyenv versions
必要なバージョンはインストール
pyenv install 2.7.10
ローカルで設定する
pyenv local 2.7.10
こうすると、.python-verionというファイルができて、中身にバージョンがかかれている。このファイルを削除すれば、globalのpython versionを利用できる。
3to2の実行Pythonバージョンに注意
インストールしたのが、python3だったので、pyenvでlocal version python2にしてしまった場所では、3to2
のコマンドがないと言われる。なので、複数のファイルを変更するときは、python3で3to2
を実行し変更してから、python2に切り替えるか、python3,2ともにインストールするかなど考える必要がある。