Python2コードをPython3に移植する方法
序章
Pythonは1980年代後半に開発され、1991年に最初に公開されました。 英国のコメディグループであるモンティパイソンにちなんで名付けられたPythonは、命令型の汎用ABCプログラミング言語の後継として考案されました。 最初の反復では、Pythonにはすでに例外処理、関数、および継承を持つクラスが含まれていました。
このチュートリアルでは、Python2からPython3にコードを移行する際のベストプラクティスと考慮事項、および両方のバージョンと互換性のあるコードを維持する必要があるかどうかについて説明します。
バックグラウンド
Python 2 は2000年に公開され、より透過的で包括的な言語開発プロセスを示しています。 より多くのプログラム機能が含まれ、開発全体を通じてさらに多くの機能が追加されました。
Python 3 は、Pythonの未来と見なされており、現在開発中の言語のバージョンです。 2008年後半にリリースされたPython3は、固有の設計上の欠陥に対処して修正しました。 ただし、Python 2との下位互換性がないため、Python3の採用は遅れています。
Python 2.7 は、2.xリリースの最後として2010年に公開されました。 Python 2.7の背後にある意図は、Python2.xユーザーがPython3に機能を移植しやすくすることで、2つの間の互換性をある程度提供することでした。
チュートリアル「Python2とPython3:実用上の考慮事項」を読むことで、Pythonのバージョンと使用するバージョンの選択について詳しく知ることができます。
Python2.7から始める
Python 3に移行する、またはPython2とPython3を同時にサポートするには、Python2コードがPython2.7と完全に互換性があることを確認する必要があります。
多くの開発者はすでにPython2.7コードのみを使用していますが、以前のバージョンでのみサポートされているものがPython 2.7で正しく機能し、Python2.7スタイルと一致していることを確認することが重要です。
コードがPython2.7であることを確認することは特に重要です。これは、Python 2がまだ維持されており、バグ修正を受けている唯一のバージョンであるためです。 以前のバージョンのPython2で作業している場合は、サポートされなくなり、buxfixesを受け取らなくなったコードで発生する問題を回避する必要があります。
さらに、プログラミングエラーを探す Pylint パッケージなど、コードの移植を容易にする一部のツールは、2.7より前のバージョンのPythonではサポートされていません。
Python 2.7は現在もサポートおよび保守されていますが、最終的には保守終了になることを覚えておくことが重要です。 PEP 373 は、Python 2.7のリリーススケジュールの詳細を示しており、執筆時点では、日没日を2020としています。
テストカバレッジ
テストケースの作成は、Python2をPython3コードに移行するために行われる作業の重要な部分になる可能性があります。 Pythonの複数のバージョンを維持している場合は、各バージョンが引き続き期待どおりに機能することを保証するために、テストスイートが全体的に良好なカバレッジを持っていることも確認する必要があります。
テストの一環として、インタラクティブなPythonケースをすべての関数、メソッド、クラス、モジュールのdocstringに追加し、組み込みの doctestモジュールを使用して、それらが図のように機能することを確認できます。
doctestと一緒に、coverage.pyパッケージを使用して単体テストのカバレッジを追跡できます。 このツールはプログラムを監視し、コードのどの部分が実行されたか、どの部分が実行されたが実行されなかったかを記録します。 coverage.pyは、レポートをコマンドラインに出力したり、HTML出力を提供したりできます。 これは通常、テストの有効性を測定するために使用され、コードのどの部分がテストによって実行され、どの部分が実行されていないかを示します。
100%のテストカバレッジを目指しているのではないことに注意してください。混乱したり、異常なコードをカバーしていることを確認する必要があります。 ベストプラクティスについては、80% cの超過を目指す必要があります。
Python2とPython3の違いについて学ぶ
Python2とPython3の違いについて学ぶことで、Python3で利用できる、または利用できるようになる新機能を確実に活用できるようになります。
「Python2とPython3」に関するガイドでは、2つのバージョン間の主な違いの一部について説明しています。詳細については、公式Pythonドキュメントをご覧ください。詳細。
移植と移行を開始するとき、今実装できる構文の変更がいくつかあります。
print
The print Python2のステートメントがに変更されました print() Python3の関数。
| Python 2 | Python 3 |
|---|---|
print "Hello, World!"
|
print("Hello, World!")
|
exec
The exec Python 2のステートメントは、Python3で明示的なローカルとグローバルを許可する関数に変更されました。
| Python 2 | Python 3 |
|---|---|
exec code
|
exec(code)
|
exec code in globals
|
exec(code, globals)
|
exec code in (globals, locals)
|
exec(code, globals, locals)
|
/および//
Python 2は、 / 演算子、Python3が導入されました // フロア分割用。
| Python 2 | Python 3 |
|---|---|
5 / 2 = 2
|
5 / 2 = 2.5
|
5 // 2 = 2
|
Python 2でこれらの演算子を使用するには、__future__モジュールからimport divisionを実行します。
from __future__ import division
整数による除算の詳細をご覧ください。
raise
Python 3では、引数を使用して例外を発生させるには括弧が必要であり、stringsを例外として使用することはできません。
| Python 2 | Python 3 |
|---|---|
raise Exception, args
|
raise Exception
|
raise Exception(args)
|
|
raise Exception, args, traceback
|
raise Exception(args).with_traceback(traceback)
|
raise "Error"
|
raise Exception("Error")
|
except
Python 2では、複数の例外をリストすることは困難でしたが、Python3ではそれが変更されました。
ご了承ください as で明示的に使用されます except Python3で
| Python 2 | Python 3 |
|---|---|
except Exception, variable:
|
except AnException as variable:
|
except (OneException, TwoException) as variable:
|
def
Python 2では、関数はタプルやリストのようなシーケンスを受け取ることができます。 Python 3では、この解凍は削除されました。
| Python 2 | Python 3 |
|---|---|
def function(arg1, (x, y)):
|
def function(arg1, x_y): x, y = x_y
|
expr
Python2のバックティック構文はもう存在しません。 使用する repr() また str.format() Python3で。
| Python 2 | Python 3 |
|---|---|
x = `355/113`
|
x = repr(355/113):
|
文字列のフォーマット
文字列のフォーマット構文がPython2からPython3に変更されました。
| Python 2 | Python 3 |
|---|---|
"%d %s" % (i, s)
|
"{} {}".format(i, s)
|
"%d/%d=%f" % (355, 113, 355/113)
|
"{:d}/{:d}={:f}".format(355, 113, 355/113)
|
Python3で文字列フォーマッターを使用する方法を学びます。
class
述べる必要はありません object Python3で。
Python 2
class MyClass(object):
pass
Python 3
class MyClass:
pass
Python 3では、メタクラスは metaclass キーワード。
Python 2
class MyClass:
__metaclass__ = MyMeta
class MyClass(MyBase):
__metaclass__ = MyMeta
Python 3
class MyClass(metaclass=type):
pass
class MyClass(MyBase, metaclass=MyMeta):
pass
コードを更新
Python 2との互換性を維持しながら、コードをPython3に自動的に更新するために使用できる2つの主要なツールがあります。futureとmodernize。 これらのツールはそれぞれ動作が多少異なります。futureはPython3のイディオムを作成するために機能し、ベストプラクティスはPython 2に存在しますが、modernizeはPythonを使用するPythonのPython2/3サブセットを対象としています[ X204X]互換性を向上させるための6つのモジュール。
これらのツールを使用してコードの書き換えの詳細を処理すると、潜在的な問題やあいまいさを特定して修正するのに役立ちます。
単体テストスイートでツールを実行して、コードを視覚的に検査および検証し、行われた自動リビジョンが正確であることを確認できます。 テストに合格すると、コードを変換できます。
ここから、特に上記のセクションに記載されているPython2と3の間の変更を対象に手動で修正する必要があります。
futureを利用して、このimportステートメントを各Python2.7モジュールに追加することを検討する必要があります。
from __future__ import print_function, division, absolute_imports, unicode_literals
これは書き直しにもつながりますが、Python2コードがPython3構文と一致することを保証します。
最後に、 pyrintパッケージを使用して、コード内の他の潜在的な問題を特定できます。 このパッケージには、 PEP 8スタイルガイドルールや使用エラーなど、発生する可能性のある幅広い問題をカバーする何百もの個別のルールが含まれています。
pylintと自動移行に使用されるツールを混同する可能性のある、コード内の構造がいくつかあることに気付くかもしれません。 これらの構成を単純化できない場合は、徹底的な単体テストのケースを採用する必要があります。
継続的インテグレーション
Pythonの複数のバージョンのコードを維持する場合は、コードを開発するときに、コードを可能な限り頻繁に(手動ではなく)継続的インテグレーションを通じて単体テストスイートの実行と再実行に注意する必要があります。 。
Python 2および3の互換性メンテナンスの一部として6パッケージを使用する場合は、テストに複数の環境を使用する必要があります。
使用を検討できる環境管理ツールの1つは、 toxパッケージです。これは、パッケージがさまざまなPythonバージョンでインストールされていることを確認し、各環境でテストを実行し、継続的インテグレーションサーバーのフロントエンドとして機能します。
結論
開発者やコミュニティの注目がPython3に集中するにつれて、言語はより洗練され、プログラマーの進化するニーズに沿ったものになり、Python2.7へのサポートは少なくなることを覚えておくことが重要です。 Python2とPython3の両方のコードベースのバージョンを維持することにした場合、時間の経過とともに受け取るバグ修正が少なくなるため、前者の方が困難になる可能性があります。
chardetのPython3への移植などのケーススタディを含め、Python2をPython3に移植したプロジェクトを検討することは価値があります。