Open9

pythonのモジュールシステムをさらう

nakaakistnakaakist
  • モジュールとは
    • 定義をファイルに書いておき、他のモジュールや main モジュール(=実行のトップレベル) に importできるもの
    • モジュールは Python の定義や文が入ったファイル。ファイル名はモジュール名に接尾語 .py がついたもの。(モジュールの中では、モジュール名を__name__で取得可能)
nakaakistnakaakist
  • モジュール内の実行文
    • モジュールの中に、初期化目的で実行文を入れることができる。この実行文は、初めてインポートされたときに一度だけ実行される
  • モジュール内では、ユーザのグローバル変数との衝突は心配しなくて良い
  • importの書き方
    • from fibo import fib, fib2: 使いたいものだけインポート
    • from fibo import *: 非推奨。 fiboモジュールの中の未知の名前が読み込まれ、定義済みの名前を上書きしてしまう可能性がある
    • import fibo as fib: モジュール名を任意の名前に変えて取り扱える
nakaakistnakaakist

モジュールをスクリプトとして実行する

  • モジュールは、python fibo.pyみたいな形でも実行できる。この場合、__name__はモジュール名ではなく__main__になる。
    • つまり、if __name__ == "__main__":っていうブロックを付け加えて、そこに処理を書けば、スクリプトとしても実行できる。
    • これは、モジュールに便利なUIを提供したり、テストのために使われたりする。
nakaakistnakaakist

モジュール検索パス

  • モジュールを探す優先順位 (import spamというインポートをしたとき)
    • まず、ビルトインモジュールを探す
    • 次に、sys.pathにあるディレクトリのリストからspam.pyを探す。
      • sys.pathはどこか
        • 入力されたスクリプトのあるディレクトリ(or カレントディレクトリ)
        • PYTHONPATH
        • インストール方法によって異なるが、site-packages的なところ。(<- npmでいうところのグローバルインストールしたパッケージ的な?)
      • 一応、sys.pathをpythonプログラム内で書き換えることもでできるが、多くの場合混乱の元。
nakaakistnakaakist

「コンパイル」されたpythonファイル

  • モジュール読み込みを高速化するため、pythonはコンパイル済みモジュールを__pycache__ディレクトリの.pycファイルにキャッシュする
  • ちなみに、pycファイルの実行は、pyファイルの実行に比べて高速化しない
    • あくまで読み込みにかかる時間だけ
nakaakistnakaakist

dir()関数

  • dir(<モジュール名>)とすると、モジュール内にどんな名前が定義されているか、一覧を取得できる。(引数なしだと現在のモジュール)
nakaakistnakaakist

パッケージ

  • パッケージ = モジュールの名前空間を "ドット付きモジュール名" を使って構造化する手段
  • 例えば、import A.Bみたいに、AというパッケージのサブモジュールBをインポートできる。
    • 複数モジュールからなるパッケージをつくるときに有用
  • ファイルを含むディレクトリをパッケージとして認識させるには、__init__.pyが必要。
    • これが必要な理由は、何でもかんでもパッケージとみなしてしまうと、stringみたいな名前のディレクトリがあったときに、それが意図せずパッケージとしてみなされてしまい、他のパッケージやモジュールが隠蔽されてしまうから
    • 簡単なケースでは__init__.pyは空でもよいが、初期化処理を書いたりもできる。
nakaakistnakaakist

パッケージのインポート

  • importの書き方 (sound.efects.echoというモジュール内のechofilter関数を使いたいとする)

    • import sound.effects.echo: 関数の利用時にsound.effects.echo.echofilterと書かないといけない
    • from sound.effects import echo: 関数の利用時にecho.echofilterと書ける
    • from sound.effects.echo import echofilter: 関数の利用時にechofilterと書ける
    • from sound.effects import *: 非推奨。__init__.py__all__ = ["echo", ...]みたいな定義が書いてあれば、そのモジュールが読み込まれる。書いてなければ、sound.effectsのすべてのサブモジュールをインポートしない。
  • なお、from xxxと書くときは、xxxはパッケージもしくはモジュールじゃないといけないので注意(クラスとか関数は不可)

  • from .. import formatsみたいに相対importもできる (ただし、現在のモジュール名がベースになっていることに注意)