Python は、Python プログラマーの作業を容易にし、車輪の再発明の作業を軽減できる広範なエコシステムに進化しました。開発したツールが最終的なプログラムに含まれない場合でも、同じ概念がツール開発者の仕事にも当てはまります。この記事では、Pythonプログラマーが知っておくべき開発者ツールを紹介します。
開発者にとって最も実際的な支援は、コード ドキュメントの作成を支援することです。pydoc モジュールは、ソース コード内の docstring に基づいて、インポート可能なモジュールの適切な形式のドキュメントを生成できます。 Python には、コードを自動的にテストし、コードの正しさを検証するための 2 つのテスト フレームワークが含まれています: 1) doctest モジュール。ソース コードまたは独立したファイルのサンプルからテスト ケースを抽出できます。 2) unittest モジュール。このモジュールは、テスト フィクスチャ、事前定義されたテスト スイート、テスト ディスカバリのサポートを提供するフル機能の自動テスト フレームワークです。
trace モジュールは、Python がプログラムを実行する方法を監視し、プログラムの各行が実行された回数を表示するレポートを生成できます。この情報は、自動テスト セットでカバーされていないプログラムの実行パスを検出するために使用できます。また、プログラム コール グラフを調査してモジュール間の依存関係を検出するためにも使用できます。テストを作成して実行すると、ほとんどのプログラムで問題を見つけることができます。Python では、ほとんどの場合、未処理のエラーをコンソールに出力できるため、デバッグが容易になります。このエラーはトレースバックと呼ばれます。プログラムがテキスト コンソールで実行されていない場合、トレースバックはエラー情報をログ ファイルまたはメッセージ ダイアログ ボックスに出力することもできます。標準のトレースバックでは十分な情報が提供できない場合は、cgitb モジュールを使用して、スタックおよびソース コード コンテキストのすべてのレベルの詳細情報 (ローカル変数など) を表示できます。 cgitb モジュールは、これらの追跡情報を HTML 形式で出力して、Web アプリケーションのエラーを報告することもできます。
問題の場所がわかったら、対話型デバッガーを使用してコードを入力してデバッグする必要があります。pdb モジュールはこの仕事をうまく実行できます。このモジュールは、エラーが発生したときにプログラムの実行パスを表示したり、デバッグ用にオブジェクトやコードを動的に調整したりできます。プログラムのテストとデバッグが完了したら、次のステップはパフォーマンスに注意を向けることです。開発者は、profile モジュールと timit モジュールを使用して、プログラムの速度をテストし、プログラムが遅い箇所を見つけて、コードのこの部分を個別に調整できます。 Python プログラムはインタープリターを通じて実行され、インタープリターへの入力は元のプログラムのコンパイルされたバイトコード バージョンです。このバイトコードのコンパイルされたバージョンは、プログラムの実行時に動的に生成することも、プログラムのパッケージ化時に生成することもできます。 compileall モジュールはプログラムのパッケージ化を処理でき、インストーラーやパッケージ化ツールがモジュールのバイトコードを含むファイルを生成するために使用できるパッケージ化関連のインターフェイスを公開します。同時に、開発環境では、コンパイル モジュールを使用して、ソース ファイルに構文エラーが含まれているかどうかを確認することもできます。
ソース コード レベルでは、pyclbr モジュールはクラス ビューアを提供し、テキスト エディターやその他のプログラムが Python プログラム内の関数やクラスなどの興味深い文字をスキャンしやすくします。クラス ビューアを提供した後はコードを導入する必要がないため、潜在的な副作用を回避できます。
docstring とhelp() コマンドは docstring を検出でき、Python 関連の IDE も docstring を検出できます。プログラマは対話型シェルで docstring を表示する傾向があるため、これらの文字列を短くすることが最善です。たとえばれーれー
ドキュメントを作成するときの一般的な問題は、ドキュメントと実際のコードの同期をどのように保つかということです。たとえば、プログラマは関数の実装を変更したが、ドキュメントの更新を忘れる可能性があります。この問題を解決するには、doctest モジュールを使用します。 doctest モジュールは、docstring を収集し、スキャンして、テストとして実行します。 doctest モジュールを使用するには、通常、テスト用に新しい独立したモジュールを作成します。たとえば、前の例 Test class がファイル mult.py に含まれている場合、以下に示すように、テスト用に新しい testmult.py ファイルを作成する必要があります。 このコードでは、
doctest.testmod(module)は特定のモジュールのテストを実行し、失敗したテストの数とテストの合計数を返します。すべてのテストに合格した場合、出力は生成されません。それ以外の場合は、期待値と実際の値の差を示す障害レポートが表示されます。テストの詳細な出力を確認したい場合は、testmod(module,verbose=True).を使用できます。 別のテスト ファイルを作成したくない場合は、ファイルの最後に対応するテスト コードを含めるという別のオプションもあります:
# mult.py class Test: """ >>> a=Test(5) >>> a.multiply_by_2() 10 """ def __init__(self, number): self._number=number def multiply_by_2(self): return self._number*2
このタイプのテストを実行したい場合は、-m オプションを使用して doctest モジュールを呼び出すことができます。通常、テストを実行しても出力はありません。詳細情報を表示したい場合は、-v オプションを追加します。
りー単体テストと
unittest単体テストを使用する場合、
unittest.TestCaseを継承するクラスを定義する必要があります。このクラスでは、各テストはメソッドの形式で定義され、test で始まる名前が付けられます。たとえば、'testsimplestring'、'testtypeconvert' および同様の命名メソッド (ただし、メソッド名は test で始まり、どのような名前を付けても問題ありません)。各テスト内で、アサーションを使用してさまざまな条件をチェックできます。 実践例:
プログラムにメソッドがあり、このメソッドの出力が標準出力 (sys.stdout) を指しているとします。これは通常、テキスト情報を画面に出力することを意味します。これを証明するためにコードをテストしたい場合は、対応する入力を与えるだけで、対応する出力が表示されます。
りー組み込みの印刷関数は、デフォルトで出力を sys.stdout に送信します。出力が実際に到着したかどうかをテストするには、代用オブジェクトを使用して出力をシミュレートし、プログラムの期待値についてアサーションを行うことができます。
unittest.mock モジュールの patch() メソッドは、テスト実行のコンテキストでのみオブジェクトを置き換えることができ、テストの完了直後にオブジェクトの元の状態を返します。以下は urlprint() メソッドのテストコードです:
urlprint()函数有三个参数,测试代码首先给每个参数赋了一个假值。变量expected_url包含了期望的输出字符串。为了能够执行测试,我们使用了unittest.mock.patch()方法作为上下文管理器,把标准输出sys.stdout替换为了StringIO对象,这样发送的标准输出的内容就会被StringIO对象所接收。变量fake_out就是在这一过程中所创建出的模拟对象,该对象能够在with所处的代码块中所使用,来进行一系列的测试检查。当with语句完成时,patch方法能够将所有的东西都复原到测试执行之前的状态,就好像测试没有执行一样,而这无需任何额外的工作。但对于某些Python的C扩展来讲,这个例子却显得毫无意义,这是因为这些C扩展程序绕过了sys.stdout的设置,直接将输出发送到了标准输出上。这个例子仅适用于纯Python代码的程序(如果你想捕获到类似C扩展的输入输出,那么你可以通过打开一个临时文件然后将标准输出重定向到该文件的技巧来进行实现)。 以上がPython プログラマーが知っておくべき開発者ツールの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。#urltest.py
from io import StringIO
from unittest import TestCase
from unittest.mock import patch
import url
class TestURLPrint(TestCase):
def test_url_gets_to_stdout(self):
protocol = 'http'
host = 'www'
domain = 'example.com'
expected_url = '{}://{}.{}\n'.format(protocol, host, domain)
with patch('sys.stdout', new=StringIO()) as fake_out:
url.urlprint(protocol, host, domain)
self.assertEqual(fake_out.getvalue(), expected_url)