Pythonチュートリアル(6章)の内容を箇条書きでまとめた

前の記事：[Pythonチュートリアル(5章)の内容を箇条書きでまとめた](https://qiita.com/Wakii/items/34585aa75bf8c6a5b219)

#はじめに
[Python3 エンジニア認定基礎試験](https://www.pythonic-exam.com/exam/basic)対策として、Pythonチュートリアル(書籍)の内容を暗記しやすい箇条書きにまとめた自分用メモです。

##参考資料
Pythonチュートリアル： https://docs.python.org/ja/3/tutorial/
6章： https://docs.python.org/ja/3/tutorial/modules.html
書籍： https://www.oreilly.co.jp/books/9784873117539/

#"6章 モジュール" テーマ
- Python3 エンジニア認定基礎試験の配点
    - 2 / 40問(5.0%) ☆★★★★(重要度：小)
- テーマ
    - モジュール
        - モジュールファイル
        - モジュールのインポート
        - モジュールの検索パス
        - モジュールのコンパイルの仕組み
        - 標準モジュール
    - パッケージ
        - パッケージのインポート
        - \_\_init\_\_.py ファイル
        - \_\_all\_\_ 変数
        - \_\_path\_\_ 変数

#6. モジュール
- **モジュール**とはPythonの定義や文が入ったファイルである。 
    - モジュールのファイル名は「モジュール名.py」
    - 対話モードやトップレベルで実行されるスクリプトからアクセスできる変数の集合を**mainモジュール**という。
    - モジュール内のグローバル変数 **\_\_name__** にモジュール名がセットされている。
    - モジュールで定義されたものは別のモジュールやmainモジュールに**import**できる。
        - *import fibo* # fibo モジュールがimportされる
        - *fibo.fib(1000)* # fibo モジュールの fib() 関数を呼び出す
        - *fib = fibo.fib* # fibo モジュールの fib() 関数をローカル変数に代入
        - *print(fibo.\_\_name__)* # モジュール名 'fibo' を出力 

#6.1 さらにモジュールについて
- モジュールに実行可能な文を入れたとき、以下のタイミングで実行される。
    - モジュールをスクリプトとして実行したとき。
    - 他のモジュールから import文 で呼ばれた(モジュール名に初めて遭遇した)とき。
- モジュールはそれぞれプライベートなシンボル表を持つ。
- モジュールから他のモジュールをimportすることもできる。
- importされたモジュール名は、importした側のグローバルシンボル表に配置される。
- **from** を指定すると、モジュールの特定の名前だけをimportできる。
    - *from fibo import fib, fib2* # fibo モジュールの fib(), fib2() 関数だけをimport
    - *from fibo import ** # アンダースコア _ で始まる以外の名前をimport 
        - import * は可読性を落とすことが多いので、あまり使われない。


##6.1.1 モジュールをスクリプトとして実行する
- Pythonモジュールの実行コマンドは以下の通り。
    - *python fibo.py 引数* # 実行コマンド
- Pythonモジュールを実行すると、\_\_name__ には "\_\_main__" が入る。
    - *if \_\_name__ == "\_\_main__":* # スクリプト実行した場合のみこの下のコードを実行

##6.1.2 モジュールの検索パス
- インタープリタはimportしたモジュールを以下の順番で探す。
    1. **ビルトインモジュール** (インタープリタの組込モジュール) の中
    2. **sys.path 変数**で得られるディレクトリのリスト
- sys.path は以下の場所で初期化されている。
    - 入力スクリプトのあるディレクトリ
        - ファイル名が指定されていない場合はカレントディレクトリ
    - PYTHONPATH (ディレクトリ名のリスト)
    - インストールごとのデフォルト
- シンボリックリンクを置いてあるディレクトリはモジュール検索パスに入らない。
- sys.path は初期化後にプログラムから改変可能。
- 実行中のスクリプトのあるディレクトリは、検索パスの最初に置かれる。
    - 検索順序は標準ライブラリのパスより前。
        - (注意)標準ライブラリのモジュールと同名のスクリプトを置くと、そちらが優先的にロードされてしまう。

##6.1.3 「コンパイル済」Pythonファイル
- Pythonはコンパイル済モジュールを **\_\_pycache__ ディレクトリ**にキャッシュする。
    - キャッシュ名は、module.バージョン名.pyc
        - **バージョン名**はコンパイルされたファイル形式のコードでPythonのバージョン番号を含む。
- コンパイル済モジュールはプラットフォーム非依存。
- Pythonはソースコードの更新日時とキャッシュのバージョンを比較し、再コンパイル要否を判断する。
- 以下の場合はキャッシュのチェックが行われない。
    - モジュールがコマンドラインから直接ロードされるとき。
        - この場合、常に再コンパイルが行われ結果を保存しない。
    - モジュールのソースファイルがないとき。 
- ソースなし配布をサポートするには、以下が必須となる。
    - コンパイル済モジュールをソースディレクトリに置くこと。
    - ソースファイル自体は置かないこと。

#6.2 標準モジュール
- Pythonには標準モジュールのライブラリが付属する。
- モジュール構成はインストール時の設定で決まる。
- インタープリタ組込やプラットフォーム依存のモジュールもある。
    - インタープリタ組込モジュールは、性能上の必要性やOSプリミティブへのアクセス提供のために用意されている。
    - プラットフォーム依存モジュールには、Windows用の winreg モジュールなどがある。
- **sys モジュール**は、すべてのPythonインタープリタに組み込まれている。
    - sys.ps1 ... プライマリプロンプトの文字列定義 ('>>>')
    - sys.ps2 ... セカンダリプロンプトの文字列定義 ('...')
        - この二つは、インタープリタが対話モードの場合のみ定義されている。
    - sys.path ... インタープリタのモジュール検索パスを指定する文字列リスト
        - sys.path の初期値には以下のディレクトリ。
            - 入力スクリプトのあるディレクトリ
                - ファイル名が指定されていない場合はカレントディレクトリ
            - 環境変数 PYTHONPATH
            - 組込みのデフォルト
 
#6.3 dir() 関数
- **dir() 関数**は、モジュールが定義している名前を文字列のソート済リストで返す。
    - 引数にモジュール名を指定すると、そのモジュールが定義する名前を返す。
    - 引数を指定しない場合、現在のレベルで定義されている名前を返す。
    - 名前には、変数、関数、モジュール名などが含まれる。
        - ビルトインの関数名や変数名を返す場合、builtinsモジュールをimportする。
            - *dir(builtins)* ... ビルトインの名前リストを取得する

#6.4 パッケージ
- **パッケージ**は「ドット区切りモジュール名」を使ってPythonのモジュール名を構築する。
- パッケージの実体は、ディレクトリの階層構造とその中のモジュール(.pyファイル)の集合。
- パッケージを構成するディレクトリには **\_\_init__.py ファイル**を含む必要がある。
    - \_\_init__.py ファイルの用途：
        - パッケージの初期化コードの実行
        - **\_\_all__ 変数**(後述)のセット
 
##6.4.1 パッケージから * をインポート
- パッケージに対してimport * を指定したときの挙動は以下の通り。
    - \_\_init\_\_.py ファイルに \_\_all__ 変数が定義されている場合、\_\_all__ 変数で定義されているサブモジュールをimportする。
    - \_\_all__ 変数が定義されていない場合、以下がimportされる。
        - 該当パッケージのimport
        - パッケージ本体で定義されている全ての名前
        - \_\_init\_\_.py ファイルの中で定義されている名前や明示的にロードされているサブモジュール


##6.4.2 パッケージ内の相互参照
- パッケージがサブパッケージで構成されている場合、姉妹パッケージの参照方法は以下の二つ。
    - **絶対import** ... from モジュール名(絶対パス) import 名前
    - **相対import** ... ftom モジュール名(相対パス) import 名前
        - 相対パスとして、.(カレントモジュールの階層)や ..(親階層) を使う。 
- メインモジュールとして使うことがあるモジュールからは絶対importを使うこと。
    - 名前が常に "\_\_main\_\_" になるため。

##6.4.3 複数のディレクトリにまたがるパッケージ
- **\_\_path\_\_ 変数**には、初期値に \_\_init\_\_.pyが存在するディレクトリを含んだリストが入る。
    - 初期化は \_\_init\_\_.py の実行前に行われる。
- この変数を書き換えることで、パッケージに含まれるモジュールやサブパッケージの検索に影響を及ぼすことができる。

次の記事：Pythonチュートリアル(7章)の内容を箇条書きでまとめた(作成中)