13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonにおいて __init__ やや __main__ は様々なところで出てくる。
部分的に覚えるのは良いが、各それぞれに対して目的があるので曖昧に同じような意味と誤解しないため覚えておいた方がよいと思います。
ですので、各場所でどのようなことをしているのか一覧化します。

1. __main__.py

このファイルはPythonパッケージををスクリプトとして実行することができます。
よく実行用のファイルとして定義されるmain.pyとは別物です。
簡単に実行例を示します。

プロジェクト構成
demo
  ├── __init__.py
  ├── __main__.py
  └── echo.py
コマンドライン
python3 -m echo
__init__.py
from . import echo

echo.echo("__init__ から実行")
__main__.py
from .echo import echo

echo("__main__.pyから実行")
echo.py
def echo(text="not text"):
    print(text)
実行結果
__init__.pyから実行
__main__.pyから実行

上記のような構成でスクリプトのように実行した場合、__init__.py__main.pyファイルが実行される。

今度はプログラム上からパッケージを呼び出すようにプロジェクト構成を以下のように替え、main.pyを実行してみる。

プロジェクト構成
demo
  ├── __init__.py
  ├── __main__.py
  └── echo.py
main.py
main.py
import demo
コマンドライン
python3 main.py
実行結果
__init__.pyから実行

上記の実行結果のように__init__.pyのみ実行され__main__.pyは実行されない。
これをみてmain.pyでいいんじゃないかと思うが、パッケージに実行用にファイルを用意しているため、例にあるmain.pyファイルから__main__.pyは参照できないようになっている。

2. __name__ == '__main__'

実行ファイルにパッケージとしてimportで読みだされた時に実行されないように、条件式でコマンドラインベースで直接呼び出されたかを判定させるために使用する。
基本的な使い方は以下のように用いる。

main.py
def main():
    ...

if __name__ == '__main__':
    main()
print(__name__)

>>> __main__

上記のように書くことでコマンド上でpython main.pyのように実行した時に、__name__ == '__main__'の条件がTrueになるため、main関数を実行することができる。

逆にmain.pyファイルを別の箇所から読みだしてみる。
下記のようなファイルを用意し、python call.pyを実行する。
そうすると、mainと出力され表示され、拡張子なしのファイル名が表示される。

call.py
import main()

>>> main

3. __init__.py

このファイルがあるフォルダをPythonパッケージとして認識させるためにあるファイル。モジュール検索をする名前空間の目印の役目を持っている。そのため、以下のようなフォルダ構成があるとするとdir3をimportするにはimport dir1.dir2.dir3と書くことでdir3を読み込むことができる。
ちなみに同階層にある場合は fron . import xxのようにピリオドで現在位置を指定できる。

フォルダ構成
dir1
  ├──  __init__.py
  └── dir2
       ├──  __init__.py
       └── dir3
            └── __init__.py

また、__init__.py内に書かれたコードはimprtされた時点で実行される。

3. def __init__(self): ...

Classからインスタンスを生成する際に実行するコンストラクタと呼ぶ初期化するメソッドです。
以下に実行例を示します。インスタンスを生成したときに呼び出されるため、A()と実行したものにはインスタンス生成と表示される。
A.call()のようにインスタンスを作成せずに実行するとインスタンス生成は表示されず、callのみが表示される。
@staticmethosというデコレータは指定することでインスタンスと紐づかずにメソッド実行することができるようになる。

Python
Class A:
   def __init__(self):
       print('インスタンス生成')
   
   @staticmethod
   def call():
      print('call')

a = A()
>>> インスタンス生成
A()
>>> インスタンス生成
A.call
>>> call
13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?