Pythonのmain関数とimportについて

X
     この記事はプロモーションを含みます
Content

if __name__ == “__main__”: このメインの書式ですが if __name__ というのは変数ですか?

if __name__ == "__main__": という書式において、__name__はPythonにおける特殊な組み込み変数(ビルトイン変数)です。この変数は、Pythonスクリプトが実行される際に自動的に定義されます。

  • スクリプトが直接実行された場合(例:python my_script.py)、__name__変数は"__main__"という文字列に設定されます。
  • スクリプトが他のスクリプトにインポートされた場合(例:import my_script)、__name__変数はそのスクリプトのモジュール名(この場合は"my_script")に設定されます。

この特性を利用して、if __name__ == "__main__":という条件文は、スクリプトが直接実行された場合にのみ特定のコードブロックを実行するために使用されます。

以下はその使用例です。このコードはPEP8に準拠しており、各行にコメントも付けています。

# 関数の定義
def my_function():
    print("This is my function.")

# if __name__ == "__main__" ブロック内のコード
if __name__ == "__main__":
    print("This script is being run directly.")
    my_function()

このスクリプトが直接実行された場合、出力は以下のようになります。

This script is being run directly.
This is my function.

しかし、このスクリプトが他のスクリプトからインポートされた場合、if __name__ == "__main__": ブロック内のコードは実行されません。これにより、モジュールとして再利用しやすいコードを書くことができます。

マコト

ということは 例えば soruce1.py を作り def sample_functionA という関数を定義して そのソースの最下部に メインルーチンを記載してある場合、そのsoruce1.py単体を稼働させた場合は そのメインルーチンが実行されるが 他の other.pyが source1.py をインポートした場合は other.pyが sample_functionA を利用でき その other.pyのメインルーチンが稼働するいうことですね?

じぴ子

はい、その通りです。source1.pydef sample_functionAという関数が定義されていて、その最下部にif __name__ == "__main__":というメインルーチンが記載されている場合、以下のような挙動になります。

  1. source1.pyを直接実行する(python source1.py)と、sample_functionAが定義され、その後でif __name__ == "__main__":ブロック内のメインルーチンが実行されます。
  2. 別のスクリプトother.pyからimport source1としてsource1.pyをインポートすると、sample_functionAはインポートされますが、if __name__ == "__main__":ブロック内のメインルーチンは実行されません。

このように、if __name__ == "__main__":は、スクリプトが直接実行された場合と、他のスクリプトからインポートされた場合で、どの部分を実行するかを制御する便利な仕組みです。これにより、同じ.pyファイルをスクリプトとしても、ライブラリ(モジュール)としても使えるようになります。

Pythonのインポート importについて

マコト

other.py に source1.py を インポートする書式は?

じぴ子

other.pyからsource1.pyをインポートする基本的な書式は以下のいずれかです。

  1. 全ての名前をインポートする場合: from source1 import * この書式では、source1.py内で定義されているすべての名前(関数、変数、クラスなど)がother.pyで利用可能になります。ただし、この方法は通常推奨されません。なぜなら、どの名前がインポートされているのかが明確でなく、名前の衝突が起きやすいからです。
  2. 特定の名前だけをインポートする場合: from source1 import sample_functionA この書式では、source1.py内で定義されているsample_functionAだけがother.pyで利用可能になります。
  3. モジュール全体をインポートする場合: import source1 この書式では、source1.py内で定義されている名前はsource1.プレフィックスをつけてother.pyで利用できます。例:source1.sample_functionA()
  4. モジュール全体を別名でインポートする場合:
    python import source1 as s1
    この書式では、source1.pys1という名前でother.py内で利用できます。例:s1.sample_functionA()

各行にコメントを入れると、PEP8に準拠した形になります。例えば:

# source1.pyからsample_functionAをインポート
from source1 import sample_functionA

# sample_functionAを使用
sample_functionA()

これらの書式を使って、other.pyからsource1.py内の関数や変数を利用できます。

マコト

from source1 import sample_functionA この書式はsource1.pyの特定の関数をインポートするのはわかりました。 例えばこのような関数を2つインポートしたい場合はそれぞれ上記の書式で別々に宣言すべきですか? それとも複数まとめて宣言できますか?

じぴ子

複数の関数をまとめてインポートすることも可能です。カンマ,を使って関数名を列挙することで、一行で複数の関数をインポートできます。

例えば、source1.pysample_functionAsample_functionBという2つの関数が定義されている場合、以下のように書くことができます。

# source1.pyからsample_functionAとsample_functionBをインポート
from source1 import sample_functionA, sample_functionB

この書式により、sample_functionAsample_functionBが現在のスクリプトで利用可能になります。

もちろん、PEP8に準拠した形で各行にコメントを入れることもできます。

# source1.pyからsample_functionAとsample_functionBをインポート
from source1 import sample_functionA, sample_functionB

# sample_functionAとsample_functionBを使用
sample_functionA()
sample_functionB()

このように、一行で複数の関数や変数をインポートすることができます。ただし、インポートする項目が多くなると行が長くなる可能性がありますので、その場合は複数行に分けることも考慮に入れてください。

複数のimportする場合の書式について

マコト

from source1 import sample_functionA,
sample_functionB,sample_functionC, sample_functionD,
sample_functionE,
sample_functionF
このような変則的な書き方でも認識しますか?

じぴ子

Pythonでは、そのような書き方は構文エラーになります。複数行に分けてインポートする場合は、行の末尾にバックスラッシュ(\)を置くか、括弧を使用してください。

1.バックスラッシュを使用する場合:

from source1 import sample_functionA, \
                   sample_functionB, \
                   sample_functionC, \
                   sample_functionD, \
                   sample_functionE, \
                   sample_functionF

2.括弧を使用する場合:

from source1 import (sample_functionA,
                     sample_functionB,
                     sample_functionC,
                     sample_functionD,
                     sample_functionE,
                     sample_functionF)

どちらの方法もPEP8に準拠しています。括弧を使用する方法はよりPythonicであり、多くの場合で推奨されています。この方法では、各行にコメントを追加することも容易です。

# source1.pyから複数の関数をインポート
from source1 import (
    sample_functionA,  # Aに関する説明
    sample_functionB,  # Bに関する説明
    sample_functionC,  # Cに関する説明
    sample_functionD,  # Dに関する説明
    sample_functionE,  # Eに関する説明
    sample_functionF   # Fに関する説明
)

このように書くことで、コードの可読性も高まります。

マコト

ふむ。
from source1 import (sample_functionA,
sample_functionB,sample_functionC,
sample_functionD,
sample_functionE,sample_functionF)

可読性は置いておいて これは認識しますか?

じぴ子

はい、その書き方でもPythonは正しく認識します。括弧内では、改行やスペースが許容されています。ただし、このような書き方は一般的には推奨されません。なぜなら、可読性が低く、コードのスタイルが一貫していないからです。

PEP8に準拠すると、各関数名の後にカンマを置き、改行してインデントを揃えるのが一般的です。これにより、コードの可読性が高まります。

from source1 import (
    sample_functionA,
    sample_functionB,
    sample_functionC,
    sample_functionD,
    sample_functionE,
    sample_functionF
)

しかし、技術的にはあなたが示した書き方も問題なく動作します。

  • URLをコピーしました!

この記事を書いた人

makotoのアバター makoto Blogger&YouTuber

サーバー管理者として17年ほど仕事でサーバー触ってました。
www,mail,dns,sql各鯖をすべてFreeBSDで運用してましたが現世ではかなりレアなタイプになるみたいですね笑

viやシェルスクリプトとかperlとかgccとかFreeBSDとか実はbashよりtcshが好きとか時々寝ぼけるのは
その名残でしょう。

今まで縁の下の力持ち的な他人のためにプログラムを書き他人のためにサーバー構築し他人のためにWEBサイトを創る的な世界から
自分の好きなことに集中できる環境は実に気持ち良いですね。
現役は引退済みなので難しいことはやりませんしやれません。

現在 ほぼ自由人。

Content