ごぶさたです。
最近はずっと何も書けない状態が続いています。4月から始めた仕事も少しずつですが慣れてきました。
現在、私はプロジェクトに参加していて、そこではPython2でプログラムを書いています。上司に「このプロジェクトには続きがあって、第二弾がこれからある」と言われました。
そのとき私は「現在ではPython2で書かれていますが、第二弾はPython3で書かれるのですか?」と尋ねました。 すると「引き続き、2で書く。3で書こうとするならば、ほとんど最初から書き直さなければならないからね。 続編のプロジェクトだから今やっているプロジェクトで使われているプログラムを使う。」と答えました。
また、友達に「いま参画しているプロジェクトではPython2で書かれている」と伝えたら、「それは大変だね」と同情されました。
そんな話を聞かれたので「Python2とPython3はそれほどまでに違うのか?」と思いました(今でも少しそうです)。
そこで今回は、私が気づいたPython2とPython3の違いについてまとめてみたいと思います。
またこれは違いがわかり次第、何回も更新して追記したいと思います。
プリント関数について
Python2では「print "Hello"」でもOKですが、Python3だとエラーになります。カッコ()がないとエラーが出ます。
#Python2だとOKだが、Python3だとエラーが表示される。 print "Hello" #Python3では次のようにカッコ()を使わなければならない。 print("Hello")
辞書型について
Pythonには辞書型というものがあります。リスト型やタプル型などと同じような感じです。書き方はPython2と3では同じですが、少し異なっているところもあります。
基本的には辞書型は次のように書きます。
#辞書型の基本形 dictionary = {'key1': 'value1', 'key2': 'value2'} dict_key = dictionary.keys() dict_value = dictionary.values() print(dict_key) print(type(dict_key)) print(dict_value) print(type(dict_value))
すると、dict_keyではkeyの部分が得られて、dict_valueにはvalueの部分が得られます。つまり、dict_keyでは「'key1' 'key2'」が得られて、dict_valueでは「'value1' 'value2'」が得られます。
問題はそのような要素の集め方です。Python2と3では次のような違いが生じます。
まずはPython2のほうです。
#Python2での上のプログラムの結果 #dict_key ['key1', 'key2'] #dict_keyの型はリスト型 <class 'list'> #dict_value ['value1', 'value2'] #dict_valueの型はリスト型 <class 'list'>
つまり、こちらではリスト型となります。
他方、Python3では次のようになります。
#Python3での上のプログラムの結果 #dict_key dict_keys(['key1', 'key2']) #dict_keyの型はdic_key型 <class 'dict_keys'> #dict_value dict_values(['value1', 'value2']) #dict_valueの型はdic_value型 <class 'dict_values'>
つまり、Python3ではそれぞれdict_keys型とdict_values型となり、リスト型ではありません。したがって、python3のときはリスト型に変換してから、要素をとるといったことをしなければなりません。
次のプログラムはPython2では正常に動きますが、3ではエラーが発生します。
#Python2では正常に動くが、3ではエラーが発生する。 dic = {"apple":1, "banana":2} dic_key = dic.keys() dic_value = dic.values() print(dic_key[0]) print(dic_value[0]) #Python2では次の結果が出る。 #print(dic_key[0]) "apple" #print(dic_value[0]) 1
もしもPython3で上と同じようにしたい場合は、dic_keys型やdic_values型をリスト型に変換してからしなければなりません。
#Python3で正常に動かすために dic = {"apple":1, "banana":2} dic_key = dic.keys() dic_value = dic.values() print(list(dic_key)[0]) print(list(dic_value)[0]) #結果 "apple" 1
unittestについて
unittestというモジュールがあります。それについてPython2と3はかなり異なっています。
インポートについて
Python2ではpipでインストールしなければなりません(標準ライブラリではありません)。pipでインストールした後、インポートするときは次のように書きます。
#Python2でのunittestのインポート import unittest from mock import patch from mock import mock_open
ここで、もしも「from unittest.mock import patch」と書くとエラーが出ます。しかし2.7の説明書ではそのような書き方でインポートしています。ですので、もしかしたらこの書き方でも大丈夫なのかもしれません。
https://cpython-test-docs.readthedocs.io/en/latest/library/unittest.mock.html
他方でPython3においてはunittestは標準ライブラリです。インストールする必要はありません。インポートするときは次のように書きます。
#Python3でのunittestのインポート from unittest.mock import patch, mock_open
逆に、先ほどのPython2のように
「
import unittest
from mock import patch
」
と書くとエラーが生じます(理由はわかりません)。
open関数にパッチをかける方法について
Python2では「'__builtin__.open'」と書きますが、Python3では「'builtins.open'」と書きます。
(例はいつか書きます)。
追記 2019/07/02: 組み込み関数range()について
Python2では、range()とxrange()があります。ですが、Python3ではrange()のみしかありません。
#Python2でのrange()関数の基本 print(range(3)) #結果 [0, 1, 2] #型はリスト型。 print(type(range(3))) #結果 <type 'list'>
xrange()関数はprint()で出力しても中身の数字は表示されません。型はxrange型という特別なものです。
#Python2でのxrange関数の基本 print(xrange(3)) print(type(xrange(3))) #結果 xrange(3) <type 'xrange'>
xrange関数はfor文などで使われます。もちろんrange関数でも問題ありません。
#range関数でのfor文 for i in range(3): print(i) #range関数での結果 0 1 2 #xrange関数でのfor文 for i in xrange(3): print(i) #xrange関数での結果 0 1 2
このようにPython2ではxrange関数が使えますが、Python3ではxrange関数はエラーが生じます。つまり、使えません。
print(xrange(3)) NameError Traceback (most recent call last) <ipython-input-12-50e3fec3bafd> in <module> ----> 1 print(xrange(3)) NameError: name 'xrange' is not defined
さらにPython3ではrange()はrange型です。リスト型ではありません。
#Python3でのrange関数の基本 print(range(3)) print(type(range(3))) #結果 range(0, 3) <class 'range'>
明示的にrange()を表示するならば、リスト型に変換する必要があります。また、Python2のxrange()と同じように、for文に対してこのままrange(3)を使うことができます。
#range関数を明示的にリスト型に変換する。 print(list(range(3))) #結果 [0, 1, 2] #for文に対して、リスト型に変換する方法。 for i in list(range(3)): print(i) #結果 0 1 2 #for文に対して、range関数をそのまま使う方法。 for i in range(3): print(i) #結果 0 1 2
普通、for文のときは、リスト型に変換せずに、for i in range(3): と使います。
僕から以上