Python インタプリタを終了させ、再び起動すると、これまでに行ってきた定義 (関数や変数) は失われています。ですから、より長いプログラムを書きたいなら、テキストエディタを使ってインタプリタへの入力を用意しておき、手作業の代わりにファイルを入力に使って動作させるとよいでしょう。この作業を スクリプト (script) の作成と言います。プログラムが長くなるにつれ、メンテナンスを楽にするために、スクリプトをいくつかのファイルに分割したくなるかもしれません。また、いくつかのプログラムで書いてきた便利な関数について、その定義をコピーすることなく個々のプログラムで使いたいと思うかもしれません。
こういった要求をサポートするために、Python では定義をファイルに書いておき、スクリプトの中やインタプリタの対話インスタンス上で使う方法があります。このファイルを モジュール (module) と呼びます。モジュールにある定義は、他のモジュールや main モジュール (実行のトップレベルや電卓モードでアクセスできる変数の集まりを指します) に import (取り込み) することができます。
モジュールは Python の定義や文が入ったファイルです。ファイル名はモジュール名に接尾語 .py がついたものになります。モジュールの中では、(文字列の) モジュール名をグローバル変数 __name__ で取得できます。例えば、お気に入りのテキストエディタを使って、現在のディレクトリに以下の内容のファイル fibo.py を作成してみましょう。
# フィボナッチ数列モジュール
def fib(n): # nまでのフィボナッチ級数を出力
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
def fib2(n): # nまでのフィボナッチ級数を返す
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a+b
return result
次に Python インタプリタに入り、モジュールを以下のコマンドで import しましょう。
>>> import fibo
この操作では、 fibo で定義された関数の名前を直接現在のシンボルテーブルに入力することはありません。単にモジュール名 fibo だけをシンボルテーブルに入れます。関数にはモジュール名を使ってアクセスします。
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
関数を度々使うのなら、ローカルな名前に代入できます。
>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
モジュールには、関数定義に加えて実行文を入れることができます。これらの実行文はモジュールを初期化するためのものです。これらの実行文は、モジュールがどこかで 最初に import された時にだけ実行されます。 [1]
各々のモジュールは、自分のプライベートなシンボルテーブルを持っていて、モジュールで定義されている関数はこのテーブルをグローバルなシンボルテーブルとして使います。したがって、モジュールの作者は、ユーザのグローバル変数と偶然的な衝突が起こる心配をせずに、グローバルな変数をモジュールで使うことができます。一方、自分が行っている操作をきちんと理解していれば、モジュール内の関数を参照するのと同じ表記法 modname.itemname で、モジュールのグローバル変数をいじることもできます。
モジュールが他のモジュールを import することもできます。 import 文は全てモジュールの(さらに言えばスクリプトでも)先頭に置きますが、これは慣習であって必須ではありません。 import されたモジュール名は import を行っているモジュールのグローバルなシンボルテーブルに置かれます。
import 文には、あるモジュール内の名前を、import を実行しているモジュールのシンボルテーブル内に直接取り込むという変型があります。例えば、
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
この操作は、import の対象となるモジュール名をローカルなシンボルテーブル内に取り入れることはありません (従って上の例では、 fibo は定義されません)。
モジュールで定義されている名前を全て import するという変型もあります。
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
上の操作は、アンダースコア (_) で開始する名前以外の全ての名前を import します。
一般的には、モジュールやパッケージから * を import するというやり方には賛同できません。というのは、この操作を行うとしばしば可読性に乏しいコードになるからです。しかし、対話セッションでキータイプの量を減らすために使うのは構わないでしょう。
ノート
実行効率上の理由で、各モジュールはインタープリタの 1 セッションごとに 1 回だけ import されます。従って、モジュールを修正した場合には、インタープリタを再起動させなければなりません – もしくは、その場で手直ししてテストしたいモジュールが 1 つだった場合には、例えば reload(modulename) のように reload() を使ってください。
Python モジュールを
python fibo.py <arguments>
と実行すると、 __name__ に __main__ が設定されている点を除いて import したときと同じようにモジュール内のコードが実行されます。つまりモジュールの末尾に、
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
このコードを追加することで、このファイルが import できるモジュールであると同時にスクリプトとしても使えるようになります。なぜならモジュールが “main” ファイルとして起動されたときだけ、コマンドラインを解釈するコードが実行されるからです。
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
モジュールが import された場合は、そのコードは実行されません。
>>> import fibo
>>>
この方法はモジュールに便利なユーザインターフェースを提供したり、テストのために (スクリプトをモジュールとして起動しテストスイートを実行して) 使われます。
spam という名前のモジュールが import されると、インタプリタは spam.py という名前のファイルを現在のディレクトリ内で探し、次に環境変数 PYTHONPATH に指定されているディレクトリのリストから探します。 PYTHONPATH はシェル変数 PATH と同じ構文、すなわちディレクトリ名を並べたものです。 PYTHONPATH が設定されていないか、探しているファイルが見つからなかった場合は、検索対象をインストール方法に依存するデフォルトのパスにして続けます。 Unixでは、このパスは通常 .:/usr/locall/lib/python です。
実際には、モジュールは変数 sys.path で指定されたディレクトリのリストから検索されます。 sys.path は、入力とするスクリプトの入ったディレクトリ (現在のディレクトリ)、 PYTHONPATH 、およびインストール方法依存のデフォルト値を使って初期化されます。 Python プログラマは、自分の行っている操作を理解しているなら、この変数を使ってモジュール検索パスを修正したり置き換えたりすることができます。起動しようとするスクリプトの入ったディレクトリが検索パス上にあるため、スクリプトが標準モジュールと同じ名前をもたないようにすることが重要です。さもなければ、Python が標準モジュールを import するときにスクリプトをモジュールとして import しようと試みてしまうので注意してください。このような誤りを犯すと、通常はエラーになります。詳しくは 標準モジュール を参照してください。
たくさんの標準モジュールを使うような短いプログラムの起動時間を大きく高速化するために、 spam.py が見つかったディレクトリに spam.pyc という名前のファイルがあった場合には、このファイルをモジュール spam の “バイトコンパイルされた” バージョンであると仮定します。 spam.pyc を生成するのに使われたバージョンの spam.py のファイル修正時刻が spam.pyc に記録されており、この値が一致しなければ spam.pyc ファイルは無視されます。
通常、 spam.pyc ファイルを生成するために何かをする必要はありません。 spam.py が無事コンパイルされると、常にコンパイルされたバージョンを spam.pyc へ書き出すよう試みます。この試みが失敗してもエラーにはなりません。何らかの理由でファイルが完全に書き出されなかった場合、作成された smap.pyc は無効であるとみなされ、それ以後無視されます。 spam.pyc ファイルの内容はプラットフォームに依存しないので、 Python のモジュールのディレクトリは異なるアーキテクチャのマシン間で共有することができます。
エキスパート向けのTips:
Python インタプリタを -O フラグ付きで起動すると、最適化されたコードが生成されて .pyo ファイルに保存されます。最適化機構は今のところあまり役に立っていません。最適化機構は assert 文と SET_LINENO 命令を除去しているだけです。 -O を使うと、 すべての バイトコード (bytecode) が最適化されます。 .pyc ファイルは無視され、 .py ファイルは最適化されたバイトコードにコンパイルされます。
二つの -O フラグ (-OO) を Python インタプリタへ渡すと、バイトコードコンパイラは、まれにプログラムが正しく動作しなくなるかもしれないような最適化を実行します。現状では、ただ __doc__ 文字列をバイトコードから除去して、よりコンパクトな .pyo ファイルにするだけです。この文字列が利用できることをあてにしているプログラムがあるかもしれないので、自分の行っている操作が何かわかっているときにだけこのオプションを使うべきです。
.pyc ファイルや .pyo ファイルから読み出されたとしても、プログラムは何ら高速に動作するわけではありません。 .pyc ファイルや .pyo ファイルで高速化されるのは、読み込まれるときの速度だけです。
スクリプトの名前をコマンドラインで指定して実行した場合、そのスクリプトのバイトコードが .pyc や .pyo に書き出されることはありません。従って、スクリプトのほとんどのコードをモジュールに移し、そのモジュールを import する小さなブートストラップスクリプトを作れば、スクリプトの起動時間を短縮できるときがあります。 .pyc または .pyo ファイルの名前を直接コマンドラインに指定することもできます。
一つのモジュールについて、ファイル spam.py のない spam.pyc (-O を使ったときは spam.pyo) があってもかまいません。この仕様は、Python コードでできたライブラリをリバースエンジニアリングがやや困難な形式で配布するために使えます。
compileall は、 .pyc ファイル (または -O を使ったときは .pyo ファイル) をディレクトリ内の全てのモジュールに対して生成することができます。
Python には標準モジュールのライブラリが付属しています。ライブラリは独立したドキュメント Python ライブラリリファレンス (以降 “ライブラリリファレンス”)で記述されています。モジュールによってはインタプリタに組み込まれたものがあります。インタプリタに組み込まれているモジュールが提供しているのは、言語の中核の部分ではありませんが、効率化のためや、システムコールのようなオペレーティングシステムの根本機能へのアクセス手段を提供するための操作です。これらのモジュールのセットは設定時に選択可能で、またプラットフォームにも依存します。例えば、 winreg モジュールは、 Windows でのみ提供されます。とりわけ、注目に値するモジュールが一つあります。 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')
組込み関数 dir() は、あるモジュールがどんな名前を定義しているか調べるために使われます。 dir() はソートされた文字列のリストを返します。
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',
'builtin_module_names', 'byteorder', 'callstats', 'copyright',
'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook',
'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags',
'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache',
'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
'version', 'version_info', 'warnoptions']
引数がなければ、 dir() は現在定義している名前を列挙します。
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']
変数、モジュール、関数、その他の、すべての種類の名前をリストすることに注意してください。
dir() は、組込みの関数や変数の名前はリストしません。これらの名前からなるリストが必要なら、標準モジュール __builtin__ で定義されています。
>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError',
'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError',
'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError',
'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True',
'TypeError', 'UnboundLocalError', 'UnicodeDecodeError',
'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError',
'UserWarning', 'ValueError', 'Warning', 'WindowsError',
'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__',
'__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer',
'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile',
'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float',
'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex',
'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter',
'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview',
'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range',
'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set',
'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super',
'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
パッケージ (package) は、Python のモジュール名前空間を “ドット付きモジュール名” を使って構造化する手段です。例えば、モジュール名 A.B は、 A というパッケージのサブモジュール B を表します。ちょうど、モジュールを利用すると、別々のモジュールの著者が互いのグローバル変数名について心配しなくても済むようになるのと同じように、ドット付きモジュール名を利用すると、 NumPy や Python Imaging Library のように複数モジュールからなるパッケージの著者が、互いのモジュール名について心配しなくても済むようになります。
音声ファイルや音声データを一様に扱うためのモジュールのコレクション (“パッケージ”) を設計したいと仮定しましょう。音声ファイルには多くの異なった形式がある (通常は拡張子、例えば .wav, .aiff, .au などで認識されます) ので、様々なファイル形式間で変換を行うためのモジュールからなる、次第に増えていくモジュールのコレクションを作成したりメンテナンスしたりする必要があるかもしれません。また、音声データに対して実行したい様々な独自の操作 (ミキシング、エコーの追加、イコライザ関数の適用、人工的なステレオ効果の作成など) があるかもしれません。そうなると、こうした操作を実行するモジュールを果てしなく書くことになるでしょう。以下に (階層的なファイルシステムで表現した) パッケージの構造案を示します。
sound/ トップレベルのパッケージ
__init__.py サウンドパッケージを初期化する
formats/ ファイルフォーマット変換用の下位パッケージ
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ サウンド効果用の下位パッケージ
__init__.py
echo.py
surround.py
reverse.py
...
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 を除く各要素はパッケージでなければなりません。最後の要素はモジュールかパッケージにできますが、一つ前の要素で定義されているクラスや関数や変数にはできません。
それでは、ユーザが from sound.effects import * と書いたら、どうなるのでしょうか?理想的には、何らかの方法でファイルシステムが調べられ、そのパッケージにどんなサブモジュールがあるかを調べ上げ、全てを import する、という処理を望むことでしょう。これには長い時間がかかってしまうこともありますし、あるサブモジュールを import することで、そのモジュールが明示的に import されたときのみ発生して欲しい副作用が起きてしまうかもしれません。
唯一の解決策は、パッケージの作者にパッケージの索引を明示的に提供させるというものです。 import 文は次の規約を使います: パッケージの __init__.py コードに __all__ という名前のリストが定義されていれば、 from package import * が現れたときに import するリストとして使います。新たなパッケージがリリースされるときにリストを最新の状態に更新するのはパッケージの作者の責任となります。自分のパッケージから * を import するという使い方に同意できなければ、パッケージの作者はこの使い方をサポートしないことにしてもかまいません。例えば、ファイル sounds/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 を行うモジュールが他のパッケージと同じ名前を持つサブモジュールを使わなければならない場合を除いて推奨される方式です。
サブモジュール同士で互いに参照を行う必要がしばしば起こります。例えば、 surround モジュールは echo モジュールを使うかもしれません。このような参照はよくあることなので、 import 文を実行すると、まず最初に import 文の入っているパッケージを検索し、その後になって標準のモジュール検索パスを見に行きます。なので、 surround モジュールは単に import echo や from echo import echofilter を使うことができます。 import されたモジュールが現在のパッケージ(現在のモジュールをサブモジュールにしているパッケージ) 内に見つからなかった場合、 import 文は指定した名前のトップレベルのモジュールを検索します。
パッケージが (前述の例の sound パッケージのように) サブパッケージの集まりに構造化されている場合、絶対 import を使って兄弟関係にあるパッケージを参照できます。例えば、モジュール sound.filters.vocoder で sound.effects パッケージの echo モジュールを使いたいとすると、 from sound.effects import echo を使うことができます。
Python 2.5 からは、上で説明した暗黙の相対importに加えて、明示的な相対importを from module import name の形式の import 文で利用できます。この明示的な相対 import では、先頭のドットで現在および親パッケージを指定します。 surround モジュールの例では、以下のように記述できます。
from . import echo
from .. import formats
from ..filters import equalizer
明示的および暗黙的な相対 import のどちらも現在のモジュール名をベースにすることに注意してください。メインモジュールの名前は常に "__main__" なので、 Python アプリケーションのメインモジュールとして利用されることを意図しているモジュールでは絶対 import を利用するべきです。
パッケージはもう一つ特別な属性として __path__ をサポートしています。この属性は、パッケージの __init__.py 中のコードが実行されるよりも前に、 __init__.py の収められているディレクトリ名の入ったリストになるよう初期化されます。この変数は変更することができます。変更を加えると、以降そのパッケージに入っているモジュールやサブパッケージの検索に影響します。
この機能はほとんど必要にはならないのですが、パッケージ内存在するモジュール群を拡張するために使うことができます。
注記
[1] | 実際には、関数定義も ‘実行’ される ‘文’ です。モジュールレベルの関数定義を実行すると、関数名はモジュールのグローバルなシンボルテーブルに入ります。 |