LoginSignup
11
17

More than 5 years have passed since last update.

python 3.x のコードをpython2.xに直す

Last updated at Posted at 2016-04-28

 背景

ずっとpython3を使っていたが、新しく入った開発で、python2で開発されていることしり、自分は3で書いてしまったが、最終的には、2に統一が必要となったので、調べた。

3to2をインストール

  1. https://pypi.python.org/pypi/3to2 から、zipをダウンロードする
  2. zipをあけ、cd 3to2-x.x.x
  3. 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ともにインストールするかなど考える必要がある。

11
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
17