6. モジュール
*************

Python インタプリタを終了させ、再び起動すると、これまでに行ってきた定
義 (関数や変数) は失われています。ですから、より長いプログラムを書きた
いなら、テキストエディタを使ってインタプリタへの入力を用意しておき、手
作業の代わりにファイルを入力に使って動作させるとよいでしょう。この作業
を *スクリプト (script)* の作成と言います。プログラムが長くなるにつれ
、メンテナンスを楽にするために、スクリプトをいくつかのファイルに分割し
たくなるかもしれません。また、いくつかのプログラムで書いてきた便利な関
数について、その定義をコピーすることなく個々のプログラムで使いたいと思
うかもしれません。

こういった要求をサポートするために、Python では定義をファイルに書いて
おき、スクリプトの中やインタプリタの対話インスタンス上で使う方法があり
ます。このファイルを *モジュール (module)* と呼びます。モジュールにあ
る定義は、他のモジュールや *main* モジュール (実行のトップレベルや電卓
モードでアクセスできる変数の集まりを指します) に *import* (取り込み)
することができます。

モジュールは Python の定義や文が入ったファイルです。ファイル名はモジュ
ール名に接尾語 ".py" がついたものになります。モジュールの中では、(文字
列の) モジュール名をグローバル変数 "__name__" で取得できます。例えば、
お気に入りのテキストエディタを使って、現在のディレクトリに以下の内容の
ファイル "fibo.py" を作成してみましょう:

   # Fibonacci numbers module

   def fib(n):    # write Fibonacci series up to n
       a, b = 0, 1
       while a < n:
           print(a, end=' ')
           a, b = b, a+b
       print()

   def fib2(n):   # return Fibonacci series up to n
       result = []
       a, b = 0, 1
       while a < n:
           result.append(a)
           a, b = b, a+b
       return result

次に Python インタプリタに入り、モジュールを以下のコマンドで import し
ましょう:

   >>> import fibo

この操作では、"fibo" で定義された関数の名前を直接現在のシンボルテーブ
ルに入力することはありません。単にモジュール名 "fibo" だけをシンボルテ
ーブルに入れます。関数にはモジュール名を使ってアクセスします:

   >>> fibo.fib(1000)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
   >>> fibo.fib2(100)
   [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
   >>> fibo.__name__
   'fibo'

関数を度々使うのなら、ローカルな名前に代入できます:

   >>> fib = fibo.fib
   >>> fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377


6.1. モジュールについてもうすこし
=================================

モジュールには、関数定義に加えて実行文を入れることができます。これらの
実行文はモジュールを初期化するためのものです。これらの実行文は、インポ
ート文の中で *最初に* モジュール名が見つかったときにだけ実行されます。
[1] (ファイルがスクリプトとして実行される場合も実行されます。)

各々のモジュールは、自分のプライベートなシンボルテーブルを持っていて、
モジュールで定義されている関数はこのテーブルをグローバルなシンボルテー
ブルとして使います。したがって、モジュールの作者は、ユーザのグローバル
変数と偶然的な衝突が起こる心配をせずに、グローバルな変数をモジュールで
使うことができます。一方、自分が行っている操作をきちんと理解していれば
、モジュール内の関数を参照するのと同じ表記法 "modname.itemname" で、モ
ジュールのグローバル変数をいじることもできます。

モジュールが他のモジュールを import することもできます。 "import" 文は
全てモジュールの(さらに言えばスクリプトでも)先頭に置きますが、これは慣
習であって必須ではありません。 import されたモジュール名は import を行
っているモジュールのグローバルなシンボルテーブルに置かれます。

"import" 文には、あるモジュール内の名前を、import を実行しているモジュ
ールのシンボルテーブル内に直接取り込むという変型があります。例えば:

   >>> from fibo import fib, fib2
   >>> fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

この操作は、import の対象となるモジュール名をローカルなシンボルテーブ
ル内に取り入れることはありません (従って上の例では、 "fibo" は定義され
ません)。

モジュールで定義されている名前を全て import するという変型もあります:

   >>> from fibo import *
   >>> fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

この書き方ではアンダースコア ("_") で始まるものを除いてすべての名前を
インポートします。殆どの場面で、Python プログラマーはこの書き方を使い
ません。未知の名前がインタープリターに読み込まれ、定義済みの名前を上書
きしてしまう可能性があるからです。

一般的には、モジュールやパッケージから "*" を import するというやり方
には賛同できません。というのは、この操作を行うとしばしば可読性に乏しい
コードになるからです。しかし、対話セッションでキータイプの量を減らすた
めに使うのは構わないでしょう。

モジュール名の後に "as" が続いていた場合は、 "as" の後ろの名前を直接、
インポートされたモジュールが束縛します。

   >>> import fibo as fib
   >>> fib.fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

これは実質的には "import fibo" と同じ方法でモジュールをインポートして
いて、唯一の違いはインポートしたモジュールが "fib" という名前で取り扱
えるようになっていることです。

このインポート方法は "from" が付いていても使え、同じ効果が得られます:

   >>> from fibo import fib as fibonacci
   >>> fibonacci(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

注釈:

  実行効率上の理由で、各モジュールはインタープリタの 1 セッションごと
  に 1 回だけ import されます。従って、モジュールを修正した場合には、
  インタープリタを再起動させなければなりません -- もしくは、その場で手
  直ししてテストしたいモジュールが 1 つだった場合には、例えば "import
  importlib; importlib.reload(modulename)" のように
  "importlib.reload()" を使ってください。


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

Python モジュールを

   python fibo.py <arguments>

と実行すると、"__name__" に "__main__" が設定されている点を除いて
import したときと同じようにモジュール内のコードが実行されます。つまり
モジュールの末尾に:

   if __name__ == "__main__":
       import sys
       fib(int(sys.argv[1]))

このコードを追加することで、このファイルが import できるモジュールであ
ると同時にスクリプトとしても使えるようになります。なぜならモジュールが
"main" ファイルとして起動されたときだけ、コマンドラインを解釈するコー
ドが実行されるからです:

   $ python fibo.py 50
   0 1 1 2 3 5 8 13 21 34

モジュールが import された場合は、そのコードは実行されません:

   >>> import fibo
   >>>

この方法はモジュールに便利なユーザインターフェースを提供したり、テスト
のために (スクリプトをモジュールとして起動しテストスイートを実行して)
使われます。


6.1.2. モジュール検索パス
-------------------------

"spam" という名前のモジュールをインポートするとき、インタープリターは
まずその名前のビルトインモジュールを探します。見つからなかった場合は、
"spam.py" という名前のファイルを "sys.path" にあるディレクトリのリスト
から探します。 "sys.path" は以下の場所に初期化されます:

* 入力されたスクリプトのあるディレクトリ (あるいはファイルが指定されな
  かったときはカレントディレクトリ)。

* "PYTHONPATH" (ディレクトリ名のリスト。シェル変数の "PATH" と同じ構文
  )。

* インストールごとのデフォルト。

注釈:

  シンボリックリンクをサポートするファイルシステム上では、入力されたス
  クリプトのあるディレクトリはシンボリックリンクをたどった後に計算され
  ます。言い換えるとシンボリックリンクを含むディレクトリはモジュール検
  索パスに追加 **されません**。

初期化された後、 Python プログラムは "sys.path" を修正することができま
す。スクリプトファイルを含むディレクトリが検索パスの先頭、標準ライブラ
リパスよりも前に追加されます。なので、ライブラリのディレクトリにあるフ
ァイルよりも、そのディレクトリにある同じ名前のスクリプトが優先してイン
ポートされます。これは、標準ライブラリを意図して置き換えているのでない
限りは間違いのもとです。より詳しい情報は 標準モジュール を参照してくだ
さい。


6.1.3. "コンパイル" された Python ファイル
------------------------------------------

モジュールの読み込みを高速化するため、Python はコンパイル済みの各モジ
ュールを "__pycache__" ディレクトリの "module.*version*.pyc" ファイル
としてキャッシュします。ここで version はコンパイルされたファイルのフ
ォーマットを表すもので、一般的には Python のバージョン番号です。例えば
、CPython のリリース 3.3 の、コンパイル済みの spam.py は
"__pycache__/spam.cpython-33.pyc" としてキャッシュされるでしょう。この
命名の慣習により、Python の異なる複数のリリースやバージョンのコンパイ
ル済みモジュールが共存できます。

Python はソースの変更日時をコンパイル済みのものと比較し、コンパイル済
みのものが最新でなくなり再コンパイルが必要になっていないかを確認します
。これは完全に自動で処理されます。また、コンパイル済みモジュールはプラ
ットフォーム非依存なため、アーキテクチャの異なるシステム間で同一のライ
ブラリを共有することもできます。

Python は2つの場合にキャッシュのチェックを行いません。ひとつは、コマン
ドラインから直接モジュールが読み込まれた場合で、常に再コンパイルされ、
結果を保存することはありません。2つめは、ソース・モジュールのない場合
で、キャッシュの確認を行いません。ソースのない (コンパイル済みのものの
みの) 配布をサポートするには、コンパイル済みモジュールはソース・ディレ
クトリになくてはならず、ソース・ディレクトリにソース・モジュールがあっ
てはいけません。

エキスパート向けのTips:

* コンパイル済みモジュールのサイズを小さくするために、Python コマンド
  に "-O" または "-OO" スイッチを使うことができます。"-O" スイッチは
  assert ステートメントを除去し、"-OO" スイッチは assert ステートメン
  トと __doc__ 文字列を除去します。いくつかのプログラムはこれらの除去
  されるものに依存している可能性があるため、自分が何をしているかを理解
  しているときに限ってこれらのオプションを使うべきです。"最適化" され
  たモジュールは "opt-" タグを持ち、通常のコンパイル済みモジュールより
  サイズが小さくなります。将来のリリースでは最適化の影響が変わる可能性
  があります。

* ".pyc" ファイルや ".pyo" ファイルから読み出されたとしても、プログラ
  ムは ".py" ファイルから読み出されたときより何ら高速に動作するわけで
  はありません。".pyc" ファイルで高速化されるのは、読み込みにかかる時
  間だけです。

* "compileall" モジュールを使ってディレクトリ内の全てのモジュールに対
  して .pyc ファイルを作ることができます。

* この処理に関する詳細は、判定のフローチャートを含めて、**PEP 3147**
  に記載されています。


6.2. 標準モジュール
===================

Python は標準モジュールライブラリを同梱していて、別の Python ライブラ
リリファレンスというドキュメントで解説しています。幾つかのモジュールは
言語のコアにはアクセスしないものの、効率や、システムコールなどOSの機能
を利用するために、インタープリター内部にビルトインされています。そうい
ったモジュールセットはまたプラットフォームに依存した構成オプションです
。例えば、 "winreg" モジュールは Windows システムでのみ提供されていま
す。 1つ注目に値するモジュールとして、 "sys" モジュールは、全ての
Python インタープリターにビルトインされています。 "sys.ps1" と
"sys.ps2" という変数は一次プロンプトと二次プロンプトに表示する文字列を
定義しています:

   >>> import sys
   >>> sys.ps1
   '>>> '
   >>> sys.ps2
   '... '
   >>> sys.ps1 = 'C> '
   C> print('Yuck!')
   Yuck!
   C>

これらの二つの変数は、インタプリタが対話モードにあるときだけ定義されて
います。

変数 "sys.path" は文字列からなるリストで、インタプリタがモジュールを検
索するときのパスを決定します。 "sys.path" は環境変数 "PYTHONPATH" から
得たデフォルトパスに、 "PYTHONPATH" が設定されていなければ組み込みのデ
フォルト値に設定されます。標準的なリスト操作で変更することができます:

   >>> import sys
   >>> sys.path.append('/ufs/guido/lib/python')


6.3. "dir()" 関数
=================

組込み関数 "dir()" は、あるモジュールがどんな名前を定義しているか調べ
るために使われます。 "dir()" はソートされた文字列のリストを返します:

   >>> import fibo, sys
   >>> dir(fibo)
   ['__name__', 'fib', 'fib2']
   >>> dir(sys)  
   ['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
    '__package__', '__stderr__', '__stdin__', '__stdout__',
    '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
    '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
    'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
    'call_tracing', 'callstats', 'copyright', 'displayhook',
    'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
    'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
    'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
    'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
    'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
    'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
    'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
    'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
    'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
    'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
    'thread_info', 'version', 'version_info', 'warnoptions']

引数がなければ、 "dir()" は現在定義している名前を列挙します:

   >>> a = [1, 2, 3, 4, 5]
   >>> import fibo
   >>> fib = fibo.fib
   >>> dir()
   ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']

変数、モジュール、関数、その他の、すべての種類の名前をリストすることに
注意してください。

"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', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
    'NotImplementedError', 'OSError', 'OverflowError',
    'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
    'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
    'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
    'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
    'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
    'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
    'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
    '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
    'all', 'any', 'ascii', 'bin', 'bool', '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']


6.4. パッケージ
===============

パッケージ (package) は、Python のモジュール名前空間を "ドット付きモジ
ュール名" を使って構造化する手段です。例えば、モジュール名 "A.B" は、
"A" というパッケージのサブモジュール "B" を表します。ちょうど、モジュ
ールを利用すると、別々のモジュールの著者が互いのグローバル変数名につい
て心配しなくても済むようになるのと同じように、ドット付きモジュール名を
利用すると、 NumPy や Pillow のように複数モジュールからなるパッケージ
の著者が、互いのモジュール名について心配しなくても済むようになります。

音声ファイルや音声データを一様に扱うためのモジュールのコレクション ("
パッケージ") を設計したいと仮定しましょう。 音声ファイルには多くの異な
った形式がある (通常は拡張子、 例えば ".wav", ".aiff", ".au" などで認
識されます) ので、増え続ける様々なファイル形式を相互変換するモジュール
を、 作成したりメンテナンスしたりする必要があるかもしれません。 また、
音声データに対して実行したい様々な独自の操作 (ミキシング、 エコーの追
加、 イコライザ関数の適用、 人工的なステレオ効果の作成など) があるかも
しれません。 そうなると、 こうした操作を実行するモジュールを果てしなく
書くことになるでしょう。 以下に (階層的なファイルシステムで表現した)
パッケージの構造案を示します:

   sound/                          Top-level package
         __init__.py               Initialize the sound package
         formats/                  Subpackage for file format conversions
                 __init__.py
                 wavread.py
                 wavwrite.py
                 aiffread.py
                 aiffwrite.py
                 auread.py
                 auwrite.py
                 ...
         effects/                  Subpackage for sound effects
                 __init__.py
                 echo.py
                 surround.py
                 reverse.py
                 ...
         filters/                  Subpackage for filters
                 __init__.py
                 equalizer.py
                 vocoder.py
                 karaoke.py
                 ...

パッケージを import する際、 Python は "sys.path" 上のディレクトリを検
索して、トップレベルのパッケージの入ったサブディレクトリを探します。

ファイルを含むディレクトリをパッケージをとしてPython に扱わせるには、
ファイル "__init__.py" が必要です。 これにより、 "string" のようなよく
ある名前のディレクトリにより、モジュール検索パスの後の方で見つかる正し
いモジュールが意図せず隠蔽されてしまうのを防ぐためです。 最も簡単なケ
ースでは "__init__.py" はただの空ファイルで構いませんが、
"__init__.py" ではパッケージのための初期化コードを実行したり、後述の
"__all__" 変数を設定してもかまいません。

パッケージのユーザは、個々のモジュールをパッケージから import すること
ができます。例えば:

   import sound.effects.echo

この操作はサブモジュール "sound.effects.echo" をロードします。このモジ
ュールは、以下のように完全な名前で参照しなければなりません。

   sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

サブモジュールを import するもう一つの方法を示します:

   from sound.effects import echo

これもサブモジュール "echo" をロードし、 "echo" をパッケージ名を表す接
頭辞なしで利用できるようにします。従って以下のように用いることができま
す:

   echo.echofilter(input, output, delay=0.7, atten=4)

さらにもう一つのバリエーションとして、必要な関数や変数を直接 import す
る方法があります:

   from sound.effects.echo import echofilter

この操作も同様にサブモジュール "echo" をロードしますが、
"echofilter()" を直接利用できるようにします:

   echofilter(input, output, delay=0.7, atten=4)

"from package import item" を使う場合、 *item* はパッケージ *package*
のサブモジュール (またはサブパッケージ) でもかまいませんし、関数やクラ
ス、変数のような、 *package* で定義されている別の名前でもかまわないこ
とに注意してください。 "import" 文はまず、 *item* がパッケージ内で定義
されているかどうか調べます。定義されていなければ、 *item* はモジュール
名であると仮定して、モジュールをロードしようと試みます。もしモジュール
が見つからなければ、 "ImportError" が送出されます。

反対に、 "import item.subitem.subsubitem" のような構文を使った場合、最
後の "subsubitem" を除く各要素はパッケージでなければなりません。最後の
要素はモジュールかパッケージにできますが、一つ前の要素で定義されている
クラスや関数や変数にはできません。


6.4.1. パッケージから * を import する
--------------------------------------

それでは、ユーザが "from sound.effects import *" と書いたら、どうなる
のでしょうか？理想的には、何らかの方法でファイルシステムが調べられ、そ
のパッケージにどんなサブモジュールがあるかを調べ上げ、全てを import す
る、という処理を望むことでしょう。これには長い時間がかかってしまうこと
もありますし、あるサブモジュールを import することで、そのモジュールが
明示的に import されたときのみ発生して欲しい副作用が起きてしまうかもし
れません。

唯一の解決策は、パッケージの作者にパッケージの索引を明示的に提供させる
というものです。 "import" 文の使う規約は、パッケージの "__init__.py"
コードに "__all__" という名前のリストが定義されていれば、 "from
package import *" が現れたときに import すべきモジュール名のリストとし
て使う、というものです。 パッケージの新バージョンがリリースされるとき
にリストを最新の状態に更新するのは パッケージの作者の責任となります。
自分のパッケージから * を import するという使い方が考えられないならば
、 パッケージの作者はこの使い方をサポートしないことにしてもかまいませ
ん。 例えば、ファイル "sound/effects/__init__.py" には、次のような コ
ードを入れてもよいかもしれません:

   __all__ = ["echo", "surround", "reverse"]

この例では、 "from sound.effects import *" とすると、 "sound" パッケー
ジから指定された 3つのサブモジュールが import されることになっている、
ということを意味します。

もしも "__all__" が定義されていなければ、実行文 "from sound.effects
import *" は、パッケージ "sound.effects" の全てのサブモジュールを現在
の名前空間の中へ import *しません* 。この文は単に(場合によっては初期化
コード "__init__.py" を実行して) パッケージ "sound.effects" が import
されたということを確認し、そのパッケージで定義されている名前を全て
import するだけです。 import される名前には、 "__init__.py" で定義され
た名前 (と、明示的にロードされたサブモジュール) が含まれます。パッケー
ジのサブモジュールで、以前の "import" 文で明示的にロードされたものも含
みます。以下のコードを考えてください:

   import sound.effects.echo
   import sound.effects.surround
   from sound.effects import *

上の例では、 "echo" と "surround" モジュールが現在の名前空間に import
されます。これらのモジュールは "from...import" 文が実行された際に
"sound.effects" 内で定義されているからです。 (この機構は "__all__" が
定義されているときにも働きます。)

特定のモジュールでは "import *" を使ったときに、特定のパターンに従った
名前のみを公開 (export) するように設計されてはいますが、それでもやはり
製品のコードでは良いことではないと考えます。

"from package import specific_submodule" を使っても何も問題はないこと
に留意してください！実際この表記法は、import を行うモジュールが他のパ
ッケージと同じ名前を持つサブモジュールを使わなければならない場合を除い
て推奨される方式です。


6.4.2. パッケージ内参照
-----------------------

パッケージが (前述の例の "sound" パッケージのように) サブパッケージの
集まりに構造化されている場合、絶対 import を使って兄弟関係にあるパッケ
ージを参照できます。例えば、モジュール "sound.filters.vocoder" で
"sound.effects" パッケージの "echo" モジュールを使いたいとすると、
"from sound.effects import echo" を使うことができます。

また、明示的な相対importを "from module import name" の形式の import
文で利用できます。この明示的な相対 import では、先頭のドットで現在およ
び親パッケージを指定します。 "surround" モジュールの例では、以下のよう
に記述できます:

   from . import echo
   from .. import formats
   from ..filters import equalizer

相対 import は現在のモジュール名をベースにすることに注意してください。
メインモジュールの名前は常に ""__main__"" なので、Python アプリケーシ
ョンのメインモジュールとして利用されることを意図しているモジュールでは
絶対 import を利用するべきです。


6.4.3. 複数ディレクトリ中のパッケージ
-------------------------------------

パッケージはもう一つ特別な属性として "__path__" をサポートしています。
この属性は、パッケージの "__init__.py" 中のコードが実行されるよりも前
に、 "__init__.py" の収められているディレクトリ名の入ったリストになる
よう初期化されます。この変数は変更することができます。変更を加えると、
以降そのパッケージに入っているモジュールやサブパッケージの検索に影響し
ます。

この機能はほとんど必要にはならないのですが、パッケージ内存在するモジュ
ール群を拡張するために使うことができます。

-[ 脚注 ]-

[1] 実際には、関数定義も '実行' される '文' です。モジュールレベルの関
    数定義を実行すると、関数名はモジュールのグローバルなシンボルテーブ
    ルに入ります。
