[Python2 / Python3] python2 から python3 にアップデート / 移行した際のソース修正項目メモ

# 概要

python2で書かれているソースコードをpython3で動かす際に発生しそうな or 発生したエラーポイントをまとめたもの。

たとえばソースを書き換える度にbuildし直す必要があるなどの事情で、なるべくソースコードの書き換え回数を抑えたい...という人には特に役に立つかも。


# 重大な補足

....と思ったら、python2からpython3へのソース書き換えを自動で行ってくれるツールがあるらしいですよ！！
知らんかった！！！！\_(-ω-`\_)⌒)\_（修正済み）

私は使っていないのですが、ソースコードの修正量が膨大な方は以下の記事などを見てみるのもありだと思います>_<。

https://docs.python.org/ja/3/library/2to3.html

http://j-parc.jp/ctrl/documents/articles/python2to3/python2python3.pdf


# 変更内容

では、手動修正時にエラーが出るポイントを見ていきましょう(・ω・´)

## 1. print

```python
# python2
print 'hoge'

# python3
print('hoge')
```

## 2. xrange

```python
# python2
for i in xrange(10):
    pass

# python3
for i in range(10):
    pass
```

以下の記事によると、`range`に書き換えてしまって問題ないとのこと。

https://www.python-izm.com/basic/range_xrange/


## 3. lambdaの引数が複数ある場合のかっこ

```python
# python2
lambda (a, b): a + b

# python3
lambda a, b: a + b
```

### python3で発生するエラー

`invalid syntax" and "sublist parameters are not supported in 3.x`

- 関連記事

https://stackoverflow.com/questions/56307412/python-syntax-error-at-key-lambda-k-v-v-k/56314856#56314856

## 4. 例外内容の取得時の記載

これは、python2でそもそも動くのかよくわかってないけど、少なくとも3では動かない気がしたので直しておいた。

```python
# python2 ???
except Exception, e;
    print(e)

# python3
except Exception as e;
    print(e)
```

## 5. cPickle

本当は`cPickle`という書き方ごと改めるのが望ましいけれど、そんなことしてたら手がかかるので、以下のようにお手軽対処♪

```python
# python2
import cPickle

# python3
import _pickle as cPickle
```

- 参考記事

https://testpy.hatenablog.com/entry/2017/03/17/000626

## 6. "文字列".encode()

文字列に対するencodeは、どうしても必要な場合以外は廃止する。

```python
# python2
"文字列".encode('ascii')

# python3
"文字列"
```

### python3で発生するエラー

`TypeError: Can't mix strings and bytes in path components`

※ただし、画像データなど、文字列以外のデータに対するencodeはこの限りではないので、必ずしも`.encode()`を除去する必要があるわけではない。

## 6. unicode を str に置き換え

```python
# python2
if type(u"文字列") == unicode:
    print('unicode !')

# python3
if type(u"文字列") == str:
    print('str !')
```

## 7. dict.iteritems()

```python
dic = {
    'key1': 'val1',
    'key2': 'val2',
}

# python2
for k, v in dic.iteritems():
    print('key: {}, val: {}'.format(k, v))

# python3
for k, v in dic.items():
    print('key: {}, val: {}'.format(k, v))
```

### python3で発生するエラー

`AttributeError: 'EasyDict' object has no attribute 'iteritems'`

- 関連記事

https://github.com/tohinz/multiple-objects-gan/issues/3

## 8. dict.has_key()

```python
# python2
if some_dict.has_key(key):
    print('There is {}'.format(key))

# python3
if key in some_dict:
    print('There is {}'.format(key))
```

### python3で発生するエラー

`AttributeError: 'EasyDict' object has no attribute 'has_key'`

https://stackoverflow.com/questions/33727149/dict-object-has-no-attribute-has-key


# おまけ

python2と直接関係ない気もするけど、もしかしたら古い書き方なのかな？
というものたち。

## 9. 自作モジュールのインポート

これはpython2からの移行だからエラーが出たのか、もともと壊れてたのかわからないけど、少なくともpython3で動かなくなっていたので、こんな修正もした。

```python
# python2
import some_module
from other_module import do_something

# python3
from . import some_module
from .other_module import do_something
```

呼び出し元と同じディレクトリ内にあるファイルをimportするときはこれで動いた。

## 10. cv2.CV_LOAD_IMAGE_COLOR

```python
# opencv version2系？
cv2.CV_LOAD_IMAGE_COLOR

# opencv version3系？
cv2.IMREAD_COLOR
```

これで動くようになった。

### opencv version3系で発生するっぽいエラー

`AttributeError: module 'cv2' has no attribute 'CV_LOAD_IMAGE_COLOR'`

- 関連記事

https://stackoverflow.com/questions/50476148/attributeerror-module-cv2-cv2-has-no-attribute-cv-load-image-color


# あとがき

今回は自分が出くわしたものだけを記述させていただきました。
実際はもっと色々な非互換ポイントがあるのだと思いますが、少しでもお役に立てていれば嬉しいです。