Pythonでのメイン関数の定義

Pythonでのメイン関数の定義

多くのプログラミング言語には、オペレーティングシステムがプログラムの実行を開始したときに自動的に実行される特別な機能があります。 この関数は通常 `+ main()+`と呼ばれ、言語標準に従って特定の戻り値の型と引数を持たなければなりません。 一方、Pythonインタープリターはファイルの先頭からスクリプトを実行し、Pythonが自動的に実行する特定の機能はありません。

それにもかかわらず、プログラムの実行のために定義された開始点を持つことは、プログラムの動作を理解するのに役立ちます。 Pythonプログラマーは、この開始点を定義するためのいくつかの規則を考案しました。

この記事の終わりまでに、次のことを理解できます。

  • 特別な `+ name +`変数とPythonの定義方法

  • Pythonで `+ main()+`を使用する理由

  • Pythonで `+ main()+`を定義するための規則は何ですか

  • あなたの `+ main()+`にどのコードを入れるのがベストプラクティスですか?

*無料ボーナス:*リンク:[Python Tricks:The Book]の章にアクセスするには、ここをクリックして、Pythonのベストプラクティスを簡単な例とともに示します。すぐに適用して、より美しい+ Pythonコードを記述できます。

基本的なPython main()

一部のPythonスクリプトでは、次の例のような関数定義と条件ステートメントが表示される場合があります。

def main():
    print("Hello World!")

if __name__ == "__main__":
    main()

このコードには、Pythonインタープリターが実行するときに「+ Hello World!」というフレーズを出力する「 main()」という関数があります。 ` name `の値をチェックし、それを文字列 `" main "`と比較する条件付き(または ` if `)ステートメントもあります。 ` if `ステートメントが ` True `に評価されると、Pythonインタープリターは ` main()+`を実行します。 条件ステートメントの詳細については、https://realpython.com/python-conditional-statements/[Pythonの条件ステートメント]を参照してください。

このコードパターンは、*スクリプトとして実行*し、*別のモジュールに*インポートしたいPythonファイルでは非常に一般的です。 このコードがどのように実行されるかを理解するには、最初にPythonインタープリターがコードの実行方法に応じて `+ name +`を設定する方法を理解する必要があります。

Pythonの実行モード

Pythonインタープリターにコードを実行または使用するよう指示できる主な方法は2つあります。

  1. コマンドラインを使用して、Pythonファイルを script として実行できます。

  2. 1つのPythonファイルから別のファイルまたはインタラクティブインタープリターにコードを*インポート*できます。

これらのアプローチの詳細については、https://realpython.com/run-python-scripts/[Pythonスクリプトの実行方法]を参照してください。 使用しているコードの実行方法に関係なく、Pythonは、コードの使用方法に依存する値を持つ文字列を含む `+ name +`という特別な変数を定義します。

`+ execution_methods.py +`として保存されたこのサンプルファイルを使用して、コンテキストに応じてコードの動作がどのように変化するかを調べます。

print("This is my file to test Python's execution methods.")
print("The variable __name__ tells me which context this file is running in.")
print("The value of __name__ is:", repr(__name__))

このファイルでは、定義された `+ print()`への3つの呼び出しがあります。 最初の2つは、導入フレーズを印刷します。 3番目の ` print()`は最初にフレーズ ` The value of name is `を出力し、次にPythonの組み込み ` repr()`を使用して ` name +`変数の表現を出力します。

Pythonでは、 `+ repr()`はオブジェクトの印刷可能な表現を表示します。 この例では、「 name 」の値が文字列であることを強調するために「 repr()」を使用しています。 ` repr()+`の詳細については、https://docs.python.org/3/library/functions.html#repr [Pythonドキュメント]を参照してください。

この記事全体で使用されている filemodule 、および script という単語が表示されます。 実際には、それらの間に大きな違いはありません。 ただし、コードの目的を強調する意味にはわずかな違いがあります。

  1. *ファイル:*通常、Pythonファイルはコードを含むファイルです。 ほとんどのPythonファイルには、拡張子「+ .py +」が付いています。

  2. スクリプト: *Pythonスクリプトは、タスクを実行するためにコマンドラインから実行するファイルです。 . モジュール:* Pythonモジュールは、別のモジュールまたはスクリプト内から、または対話型インタープリターからインポートするファイルです。 モジュールの詳細については、https://docs.python.org/3/tutorial/modules.html [Pythonドキュメント]をご覧ください。

この違いについては、https://realpython.com/run-python-scripts/[Pythonスクリプトの実行方法]でも説明しています。

コマンドラインから実行する

このアプローチでは、コマンドラインからPythonスクリプトを実行します。

スクリプトを実行すると、Pythonインタープリターが実行しているコードをインタラクティブに定義できなくなります。 コマンドラインからPythonを実行する方法の詳細は、この記事の目的にとってそれほど重要ではありませんが、下のボックスを展開して、Windows、Linux、macOSのコマンドラインの違いについて詳しく読むことができます。

次のように、コマンドラインから `+ execution_methods.py +`スクリプトを実行する必要があります。

$ python3 execution_methods.py
This is my file to test Python's execution methods.
The variable __name__ tells me which context this file is running in.
The value of __name__ is: '__main__'

この例では、 + name +`の値が `+ ' main ' +`であることがわかります。引用符( `+ '+)は、値が文字列型であることを示しています。

Pythonでは、一重引用符( + '+)と二重引用符( `+" + `)で定義された文字列に違いはないことに注意してください。 文字列の定義の詳細については、https://realpython.com/python-data-types/#strings [Pythonの基本データ型]をご覧ください。

shebang lineをスクリプトに含めて直接実行するか( +。/execution_methods.py +)、またはIPythonまたはJupyterノートブックの「+%run +」マジック。

コマンドに + -m +`引数を追加することにより、パッケージ内から実行されたPythonスクリプトを見ることができます。 ほとんどの場合、 `+ pip +`を使用しているときに、これが推奨されます: `+ python3 -m pip install package_name +

`+ -m `引数を追加すると、パッケージの ` main 。py `モジュールのコードが実行されます。 ` main 。py +`ファイルの詳細については、https://realpython.com/pypi-publish-python-package/#different-ways-of-calling-a-package [Open-を公開する方法- PyPIへのソースPythonパッケージ]。

これら3つのケースすべてで、 + name +`の値は同じです:文字列 `+ ' main ' +

技術的な詳細: Pythonのドキュメントでは、 `+ name `の値が ` ' main ' +`になるタイミングを具体的に定義しています。

_ モジュールの `+ name `は、標準入力、スクリプト、または対話型プロンプトから読み取られたときに、 ` ' main ' +`と等しく設定されます。 (https://docs.python.org/3/library/main.html [ソース]) _

+ name +`は、モジュールのグローバル名前空間に、 `+ doc ++ package +、およびその他の属性とともに格納されます。 これらの属性の詳細については、https://docs.python.org/3/reference/datamodel.html [Python Data Model documentation]をご覧ください。特にモジュールとパッケージについては、https://docs.pythonをご覧ください。 org/3/reference/import.html#import-related-module-attributes [Python Import documentation]。

モジュールまたはインタラクティブインタープリターへのインポート

次に、Pythonインタープリターがコードを実行する2番目の方法、インポートを見てみましょう。 モジュールまたはスクリプトを開発しているとき、他の誰かがすでにビルドしたモジュールを利用したいでしょう。これは、「+ import +」キーワードで実行できます。

インポートプロセス中、Pythonは指定されたモジュールで定義されたステートメントを実行します(ただし、モジュールをインポートするのは_first_ timeのみです)。 `+ execution_methods.py `ファイルをインポートした結果をデモンストレーションするには、インタラクティブなPythonインタープリターを起動してから ` execution_methods.py +`ファイルをインポートします。

>>>

>>> import execution_methods
This is my file to test Python's execution methods.
The variable __name__ tells me which context this file is running in.
The value of __name__ is: 'execution_methods'

このコード出力では、Pythonインタープリターが `+ print()`の3つの呼び出しを実行していることがわかります。 出力の最初の2行は、最初の2行のいずれにも変数がないため、コマンドラインでスクリプトとしてファイルを実行したときとまったく同じです。 ただし、3番目の ` print()+`からの出力には違いがあります。

Pythonインタープリターがコードをインポートするとき、 `+ name `の値はインポートされるモジュールの名前と同じになるように設定されます。 これは、上記の出力の3行目で確認できます。 ` name `の値は ` 'execution_methods' `で、これはPythonのインポート元の ` .py +`ファイルの名前です。

Pythonを終了せずにモジュールを再度「+ import +」すると、出力は行われないことに注意してください。

注意: Pythonでのインポートの仕組みの詳細については、https://docs.python.org/3/reference/import.html [公式ドキュメント]とhttps://realpython.com/absoluteをご覧ください。 -vs-relative-python-imports/[Pythonの絶対インポートと相対インポート]。

Pythonメイン関数のベストプラクティス

Pythonがさまざまな実行モードを処理する方法の違いを確認できたので、使用するベストプラクティスを知っておくと役立ちます。 これらは、別のモジュールまたは対話型セッションでスクリプト_and_ importとして実行できるコードを記述したいときに適用されます。

コードが2つの目的に役立つことを確認するための4つのベストプラクティスについて学習します。

  1. ほとんどのコードを関数またはクラスに入れます。

  2. コードの実行を制御するには、「+ name +」を使用します。

  3. 実行するコードを含めるために、 `+ main()+`という関数を作成します。

  4. `+ main()+`から他の関数​​を呼び出します。

ほとんどのコードを関数またはクラスに入れる

Pythonインタープリターは、モジュールをインポートするときにモジュール内のすべてのコードを実行することに注意してください。 作成するコードには、次のような副作用をユーザーに制御させる場合があります。

  • 時間がかかる計算を実行する

  • ディスク上のファイルへの書き込み

  • ユーザーの端末を混乱させる情報を印刷する

このような場合、モジュールをインポートするときにPythonインタープリターにコードを実行させるのではなく、ユーザーにこのコードの実行のトリガーを制御させます。

したがって、ベストプラクティスは、*ほとんどのコードを関数またはクラス内に含める*ことです。 これは、Pythonインタープリターが `+ def `または ` class +`キーワードを検出すると、それらの定義を後で使用するために保存するだけで、ユーザーが指示するまで実際に実行しないためです。

次のコードを `+ best_practices.py +`というファイルに保存して、このアイデアを示します。

 1 from time import sleep
 2
 3 print("This is my file to demonstrate best practices.")
 4
 5 def process_data(data):
 6     print("Beginning data processing...")
 7     modified_data = data + " that has been modified"
 8     sleep(3)
 9     print("Data processing finished.")
10     return modified_data

このコードでは、最初にhttps://realpython.com/python-time-module/[+ time + module]から `+ sleep()+`をインポートします。

`+ sleep()`は、引数として指定した秒数だけインタープリターを一時停止し、この例では実行に時間がかかる関数を生成します。 次に、 ` print()+`を使用して、このコードの目的を説明する文を印刷します。

次に、5つのことを行う `+ process_data()+`という関数を定義します。

  1. データ処理が開始されていることをユーザーに伝えるために出力を出力します

  2. 入力データを変更します

  3. `+ sleep()+`を使用して実行を3秒間一時停止します

  4. 処理が終了したことをユーザーに伝えるために出力を出力します

  5. 変更されたデータを返します

コマンドラインでベストプラクティスファイルを実行

さて、コマンドラインでこのファイルをスクリプトとして実行するとどうなりますか?

Pythonインタープリターは、関数定義の外にある `+ from time import sleep `および ` print()`行を実行し、 ` process_data()`という関数の定義を作成します。 次に、スクリプトには ` process_data()+`を実行するコードがないため、スクリプトはそれ以上何もせずに終了します。

以下のコードブロックは、このファイルをスクリプトとして実行した結果を示しています。

$ python3 best_practices.py
This is my file to demonstrate best practices.

ここで見ることができる出力は、最初の `+ print()`の結果です。 ` time `からインポートして ` process_data()`を定義すると、出力が生成されないことに注意してください。 具体的には、 ` process_data()`の定義内にある ` print()+`の呼び出しの出力は出力されません!

ベストプラクティスファイルを別のモジュールまたはインタラクティブインタープリターにインポート

このファイルを対話型セッション(または別のモジュール)にインポートすると、Pythonインタープリターはファイルをスクリプトとして実行するときとまったく同じ手順を実行します。

Pythonインタープリターがファイルをインポートすると、インポートしたモジュールで定義されている変数、クラス、または関数を使用できます。 これを実証するために、インタラクティブなPythonインタープリターを使用します。 インタラクティブインタープリターを起動して、「+ import best_practices +」と入力します。

>>>

>>> import best_practices
This is my file to demonstrate best practices.

`+ best_practices.py `ファイルのインポートからの唯一の出力は、 ` process_data()`の外部で定義された最初の ` print()`呼び出しからのものです。 コマンドラインからコードを実行したときのように、「 time 」からインポートし、「 process_data()+」を定義しても出力は生成されません。

コードの実行を制御するには、 `+ if name ==" main "+`を使用します

Pythonインタープリターがファイルをインポートするときではなく、コマンドラインからスクリプトを実行するときに `+ process_data()+`を実行したい場合はどうでしょうか。

  • + if name == "main" + イディオムを使用して実行コンテキストを決定*し、 + name + + " main " + と等しい場合にのみ、条件付きで + process_data()+ `を実行できます。 。 `+ best_practices.py +`ファイルの最後に以下のコードを追加してください:

11 if __name__ == "__main__":
12     data = "My data read from the Web"
13     print(data)
14     modified_data = process_data(data)
15     print(modified_data)

このコードでは、 `+ name `の値をチェックする条件ステートメントを追加しました。 この条件は、 ` name `が文字列 `" main "`と等しい場合、 ` True `に評価されます。 ` name `変数の `" main "+`の特別な値は、Pythonインタープリターがスクリプトを実行し、インポートしないことを意味することに注意してください。

条件ブロック内に、4行のコード(行12、13、14、および15)を追加しました。

  • * 12行目と13行目:* Webから取得したデータを保存する変数 `+ data +`を作成し、印刷しています。

  • *行14:*データを処理しています。

  • *行15:*変更したデータを印刷しています。

ここで、コマンドラインから `+ best_practices.py +`スクリプトを実行して、出力がどのように変化するかを確認します。

$ python3 best_practices.py
This is my file to demonstrate best practices.
My data read from the Web
Beginning data processing...
Data processing finished.
My data read from the Web that has been modified

最初に、出力は `+ process_data()`の外での ` print()+`呼び出しの結果を示します。

その後、 `+ data `の値が出力されます。 これは、Pythonインタープリターがファイルをスクリプトとして実行するときに変数 ` name `の値が `" main "`になり、条件文が ` True +`に評価されるために発生しました。

次に、スクリプトは `+ process_data()`を呼び出し、変更のために ` data `を渡しました。 ` process_data()`を実行すると、いくつかのステータスメッセージが出力に出力されます。 最後に、 ` modified_data +`の値が出力されます。

ここで、対話型インタープリター(または別のモジュール)から `+ best_practices.py +`ファイルをインポートしたときに何が起こるかを確認する必要があります。 以下の例は、この状況を示しています。

>>>

>>> import best_practices
This is my file to demonstrate best practices.

ファイルの最後に条件文を追加する前と同じ動作になることに注意してください! これは、 + name +`変数の値が `+" best_practices "+`だったため、条件ステートメントが `+ False +に評価されたため、Pythonは + process_data()+ `を含むブロック内のコードを実行しなかったためです。 `。

main()と呼ばれる関数を作成して、実行するコードを含める

これで、コマンドラインからスクリプトとして実行でき、望ましくない副作用なしでインポートできるPythonコードを作成できるようになりました。 次に、他のPythonプログラマーがあなたの言っていることを簡単に理解できるようにコードを記述する方法について学びます。

C、C +、Javaなどの多くの言語は、コンパイルされたプログラムの実行時にオペレーティングシステムが自動的に呼び出す「 main()+」と呼ばれる特別な関数を定義します。 この関数は、実行がプログラムに入る場所であるため、「エントリポイント」と呼ばれることがよくあります。

対照的に、Pythonには、スクリプトへのエントリポイントとして機能する特別な関数はありません。 実際には、Pythonスクリプトのエントリポイント関数に任意の名前を付けることができます!

Pythonは + main()+`という名前の関数には何の意味も割り当てませんが、ベストプラクティスは*とにかくエントリポイント関数に `+ main()+ *という名前を付けることです。 そうすれば、スクリプトを読んだ他のプログラマは、この関数がスクリプトの主要なタスクを実行するコードの開始点であることをすぐに知っています。

さらに、 `+ main()`には、Pythonインタープリターがファイルを実行するときに実行するコードを含める必要があります。 ユーザーがモジュールをインポートする場合、 ` main()+`を再利用できるため、これはコードを条件ブロックに直接配置するよりも優れています。

以下のコードのように `+ best_practices.py +`ファイルを変更します:

 1 from time import sleep
 2
 3 print("This is my file to demonstrate best practices.")
 4
 5 def process_data(data):
 6     print("Beginning data processing...")
 7     modified_data = data + " that has been modified"
 8     sleep(3)
 9     print("Data processing finished.")
10     return modified_data
11
12 def main():
13     data = "My data read from the Web"
14     print(data)
15     modified_data = process_data(data)
16     print(modified_data)
17
18 if __name__ == "__main__":
19     main()

この例では、以前に条件ブロック内にあったコードを含む `+ main()`の定義を追加しました。 次に、条件付きブロックを変更して、 ` main()+`を実行するようにしました。 このコードをスクリプトとして実行するかインポートすると、前のセクションと同じ出力が得られます。

main()から他の関数​​を呼び出す

Pythonのもう1つの一般的なプラクティスは、タスクを達成するコードを `+ main()`に含めるのではなく、 ` main()+`で他の関数を実行することです*。 これは、独立して実行できるいくつかの小さなサブタスクから全体のタスクを構成できる場合に特に便利です。

たとえば、次のことを行うスクリプトがあるとします。

  1. データベース、ディスク上のファイル、またはWeb APIなどのソースからデータファイルを読み取ります。

  2. データを処理します

  3. 処理されたデータを別の場所に書き込みます

これらの各サブタスクを別々の機能で実装すると、自分(または別のユーザー)が簡単にいくつかの手順を再利用し、不要な手順を無視できます。 次に、 `+ main()+`でデフォルトのワークフローを作成し、両方の長所を活用できます。

このプラクティスをコードに適用するかどうかは、判断の判断になります。 作業を複数の関数に分割すると、再利用が容易になりますが、プログラムのフローのいくつかのジャンプに従う必要があるため、コードを解釈しようとする他の誰かの難易度が高くなります。

`+ best_practices.py +`ファイルを変更して、以下のコードのようにします。

 1 from time import sleep
 2
 3 print("This is my file to demonstrate best practices.")
 4
 5 def process_data(data):
 6     print("Beginning data processing...")
 7     modified_data = data + " that has been modified"
 8     sleep(3)
 9     print("Data processing finished.")
10     return modified_data
11
12 def read_data_from_web():
13     print("Reading data from the Web")
14     data = "Data from the web"
15     return data
16
17 def write_data_to_database(data):
18     print("Writing data to a database")
19     print(data)
20
21 def main():
22     data = read_data_from_web()
23     modified_data = process_data(data)
24     write_data_to_database(modified_data)
25
26 if __name__ == "__main__":
27     main()

このサンプルコードでは、ファイルの最初の10行には、以前と同じ内容が含まれています。 12行目の2番目の関数定義はサンプルデータを作成して返し、17行目の3番目の関数定義は変更されたデータをデータベースに書き込むことをシミュレートします。

21行目で、 `+ main()`が定義されています。 この例では、 ` main()+`を変更して、データ読み取り、データ処理、およびデータ書き込み関数を順番に呼び出します。

最初に、 `+ read_data_from_web()`から ` data `が作成されます。 この「 data 」は「 process_data()」に渡され、「 modified_data 」が返されます。 最後に、 ` modified_data `は ` write_data_to_database()+`に渡されます。

スクリプトの最後の2行は、「+ name 」をチェックし、「 if 」ステートメントが「 True 」の場合に「 main()+」を実行する条件ブロックです。

これで、以下に示すように、コマンドラインから処理パイプライン全体を実行できます。

$ python3 best_practices.py
This is my file to demonstrate best practices.
Reading data from the Web
Beginning data processing...
Data processing finished.
Writing processed data to a database
Data from the web that has been modified

この実行の出力では、Pythonインタープリターが + main()+`を実行し、 `+ read_data_from_web()++ process_data()+、および `+ write_data_to_database()`を実行したことがわかります。 ただし、以下に示すように、 ` best_practices.py `ファイルをインポートし、異なる入力データソースに対して ` process_data()+`を再利用することもできます。

>>>

>>> import best_practices as bp
This is my file to demonstrate best practices.
>>> data = "Data from a file"
>>> modified_data = bp.process_data(data)
Beginning data processing...
Data processing finished.
>>> bp.write_data_to_database(modified_data)
Writing processed data to a database
Data from a file that has been modified

この例では、 `+ best_practices `をインポートし、このコードの名前を ` bp +`に短縮しました。

インポートプロセスにより、Pythonインタープリターは `+ best_practices.py +`ファイル内のすべてのコード行を実行するため、出力にはファイルの目的を説明する行が表示されます。

次に、Webからデータを読み取る代わりに、ファイルのデータを `+ data `に保存しました。 次に、 ` best_practices.py `ファイルの ` process_data()`と ` write_data_to_database()`を再利用しました。 この場合、 ` main()+`のすべてのロジックを定義する代わりに、コードを再利用することを利用しました。

Pythonメイン関数のベストプラクティスの概要

Pythonの `+ main()+`に関する4つの重要なベストプラクティスを以下に示します。

  1. 実行に時間がかかるコード、またはコンピューターに他の影響を与えるコードを関数またはクラスに入れて、そのコードをいつ実行するかを正確に制御できるようにします。

  2. コンテキストを決定し、条件ステートメントを使用してコードの動作を変更するには、「+ name +」のさまざまな値を使用します。

  3. Pythonが `+ main()`という名前の関数に特別な意味を割り当てない場合でも、関数の意図を伝えるためにエントリポイント関数に ` main()+`という名前を付ける必要があります。

  4. コードの機能を再利用したい場合は、 `+ main()`の外側の関数でロジックを定義し、 ` main()+`内でそれらの関数を呼び出します。

結論

おめでとうございます。 Pythonの `+ main()+`関数を作成する方法がわかりました。

次のことを学びました。

  • `+ name +`変数の値を知ることは、実行可能なスクリプトとインポート可能なモジュールの二重の目的を果たすコードを書くために重要です。

  • `+ name `は、Pythonファイルの実行方法に応じて異なる値を取ります。 ` name +`は次と等しくなります:

  • ファイルがコマンドラインから実行されるとき、またはパッケージの + main 。py +`ファイルを実行するための `+ python -m +`で `+" main "+

  • モジュールがインポートされている場合、モジュールの名前

  • Pythonプログラマーは、再利用可能なコードを開発するときに使用する一連の優れたプラクティスを開発しました。

これで、素晴らしいPython `+ main()+`関数コードを作成する準備が整いました!