LoginSignup
3
7

More than 3 years have passed since last update.

Pythonのモジュール(Python学習メモ④)

Last updated at Posted at 2019-11-12

Pythonのモジュールについて

ポイント

  • モジュール=Pythonの定義や文が入ったファイル
  • ファイル名は*.py
  • モジュールの中では、グローバル変数__name__の値としてモジュール名が設定されている
sample_module.py
def func1(n):
    return n

def func2(n):
    return n

Pythonのインタープリタにて
>>> import sample_module
>>> sample_module.func1('kawauso') 
'kawauso'

モジュールのimportについて

ポイント

  • モジュールには関数定義の他実行可能な文を入れることもできる
  • これらの文はimport時に実行されるため初期化として使う
  • モジュールはそれぞれがプライベートなシンボル表を持つため、呼び出し側との名前の衝突を気にする必要はない
  • モジュール内のグローバル変数にアクセスするには、modulename.itemnameの形で書けばよい
  • モジュールから他のモジュールも呼べる
  • 慣例としてimport文はファイルの先頭に記載する
  • モジュール内に定義されている名前を個別に呼び出すことも可能
>>> from sample_module import func1, func2
>>> func1('kawauso')
'kawauso'
>>> func2('kawauso')
'kawauso'
  • *を使用すれば、モジュールが定義する_で始まる以外のすべての名前を取り込む
  • 一般的には何がimportされるのか一見して分かりづらいため、好まれない書き方である
>>> from sample_module import *
>>> func1('kawauso')
'kawauso'

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

ポイント

  • python sample_module.py 引数にモジュールを実行することもできる
  • この時、__name____main__になる
  • これを利用して、スクリプトとして実行された場合の分岐が書ける
sample_module.py
def func1(n):
    return n

def func2(n):
    return n

# モジュールとしてインポートされたときは、このコードは走らない
if __name__ == "__main__":
    import sys
    func1(sys.argv[1])
$ python sample_module.py kawauso
kawauso

モジュールの検索パス

ポイント

  • モジュールがインポートされるとき、Pythonのインタープリタはまずビルトインモジュールを探しにいく
  • 次にsys.path変数で得られるディレクトリのリストを使ってファイル名を検索する
  • sys.pathは初期化後にプログラムから改変できる
  • 実行中のスクリプトのあるディレクトリは、検索パスの最初に置かれる
  • そのため、標準ライブラリと同名のモジュールがあれば、そちらが優先的にロードされる

コンパイル済みのPythonファイルについて

ポイント

  • モジュール読み込みの高速化のため、Pythonはコンパイル済みのモジュールを__pycache__ディレクトリにキャッシュする
  • コンパイル済みのモジュールはmodule.バージョン名.pycの名前でキャッシュされる
  • この命名規約によって異なるリリース、異なるバージョンのPythonでも共存できるようになっている
  • Pythonはソースファイルの最終変更日時をコンパイル済みのバージョンと比較し、再コンパイルが必要かどうか判断している

標準モジュール

ポイント

  • pythonには標準モジュールのライブラリが付属する
  • モジュールにはインタープリタに組み込みのものもあり、性能上の必要性やOSプリミティブな処理を行うために組み込まれる
  • これらはインストール時の設定や、プラットフォームによって決まる
  • たとえばwinregモジュールはWindowsシステムにのみ提供される
  • こういったモジュールではsysが代表的(これはすべてのPythonインタープリタで組み込みになっている)
  • sys.ps1, sys.ps2などの変数はインタープリタが対話モードの時のみ定義されている
  • sys.pathはインタープリタのモジュール検索パスを指定する文字列のリスト
  • sys.pathPYTHONPATHか、組み込みのデフォルトパスとなっている
  • これは標準のリスト操作で改変可能

dir()関数

  • ビルトイン関数dir()は、モジュールが定義している名前を確認するのに使う(返り値は文字列のリスト)
>>> import module
>>> dir(module) 
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'func1', 'func2']
  • 引数なしのdir()は現在のレベルで定義されている名前のリストを返す

>>> hoge = 'hoge' 
>>> dir()
['__annotations__', '__builtins__', 
'__doc__', '__loader__', '__name__', '__package__', '__spec__', 'hoge', 
'module']
>>>
  • dir()はビルトインの関数名と変数名をリストアップしない
  • 確認したかったら、標準モジュールbuiltinsを確認する
>>> import builtins
>>> dir(builtins) 
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 
'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 
'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 
'RecursionError', 'ReferenceError', 
'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 
'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 
'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

パッケージ

ポイント

  • パッケージは「ドット区切りモジュール名」を使ってPythonのモジュールを構築する方法
  • 例えばモジュール名A.Bは、パッケージ「A」にあるサブモジュール「B]を指す
  • あるディレクトリをパッケージを含むものと扱わせるには__init__.pyファイルが必要
  • __init__.pyは単なる空ファイルとすることもできるが、パッケージの初期化コードを実行したり、__all__変数をセットすることもできる
パッケージ構成の例
A/ -> トップレベルパッケージ
    __init__.py -> パッケージの初期化
    A1/  -> サブパッケージ1
        __init__.py
        hoge1.py
        hoge2.py
        hoge3.py
    A2/ -> サブパッケージ2
        __init__.py
        hoge1.py
        hoge2.py
        hoge3.py
パッケージの読み込み
import A.A1.hoge1
# これに対する参照はフルネームで行う必要がある
A.A1.hoge1.func1()

また、別のロード方法もある

パッケージの読み込み2
from A.A1 import hoge1
hoge1.func1()

さらに、目的の関数や変数を直接インポートする方法もある

from A.A1.hoge1 import func1
func1()

パッケージから*をインポート

ポイント

  • from A.A1 import *とするとき、パッケージの__init__.pyのコードが__all__変数を定義していた場合、そこに定義されたパッケージをimportする
  • __all__が定義されていないときは、A.A1のインポートと、パッケージ本体で定義されているすべての名前のインポートのみ
  • __init__.pyで定義された名前もインポートされる
__init__.py
__all__ = ["module1", "module2", "module3"]
module4 = func4() # module4もインポートされる
  • それまでのimport文で明示的にロードされていたサブモジュールがあれば、それもインポートされる
# echoおよびsurroundモジュールがインポートされる
import sound.effects.echo
import sound.effects.surround
from sound.effects import *

パッケージ内の相互参照

ポイント

  • パッケージがサブパッケージにより構成されているとき、姉妹パッケージの参照は絶対インポートの他、相対インポートも可能
  • 相対インポートはカレントのモジュールに基づいて行われるので、メインモジュールからは必ず絶対インポートを使うこと
  • メインモジュールの名前は常に__main__となる
from . import echo # 同じ階層
from .. import formats # 1つ上の階層
from ..filters import equalizer # 1つ上の階層のfiltersサブモジュール内

複数のディレクトリにまたがるパッケージ

ポイント

  • __path__は書き換えることでパッケージに含まれるモジュールやサブパッケージの検索に影響を与える
  • パッケージが持つモジュールの集合を拡張したいときに使える
3
7
2

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
3
7