6.6。 モジュール
Pythonインタープリターを終了して再度入力すると、作成した定義(関数と変数)は失われます。 したがって、多少長いプログラムを作成する場合は、テキストエディターを使用してインタープリターの入力を準備し、代わりにそのファイルを入力として実行することをお勧めします。 これは、スクリプトの作成として知られています。 プログラムが長くなると、メンテナンスを容易にするために、プログラムをいくつかのファイルに分割することをお勧めします。 また、定義を各プログラムにコピーせずに、いくつかのプログラムで作成した便利な関数を使用することもできます。
これをサポートするために、Pythonには、定義をファイルに入れて、スクリプトまたはインタープリターのインタラクティブインスタンスで使用する方法があります。 このようなファイルはモジュールと呼ばれます。 モジュールからの定義は、他のモジュールまたはメインモジュール(トップレベルおよび計算機モードで実行されるスクリプトでアクセスできる変数のコレクション)にインポートできます。 。
モジュールは、Pythonの定義とステートメントを含むファイルです。 ファイル名は、接尾辞.py
が付加されたモジュール名です。 モジュール内では、モジュールの名前(文字列として)がグローバル変数__name__
の値として使用できます。 たとえば、お気に入りのテキストエディタを使用して、現在のディレクトリに次の内容のfibo.py
というファイルを作成します。
# Fibonacci numbers module
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a+b
return result
次に、Pythonインタープリターを入力し、次のコマンドを使用してこのモジュールをインポートします。
>>> 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
6.1。 モジュールの詳細
モジュールには、実行可能ステートメントと関数定義を含めることができます。 これらのステートメントは、モジュールを初期化することを目的としています。 これらは、インポートステートメントでモジュール名が検出されたときに最初のでのみ実行されます。 1 (ファイルがスクリプトとして実行される場合にも実行されます。)
各モジュールには独自のプライベートシンボルテーブルがあり、モジュールで定義されているすべての関数によってグローバルシンボルテーブルとして使用されます。 したがって、モジュールの作成者は、ユーザーのグローバル変数との偶発的な衝突を心配することなく、モジュール内のグローバル変数を使用できます。 一方、自分が何をしているのかがわかっている場合は、モジュールの関数を参照するために使用されるのと同じ表記法modname.itemname
を使用してモジュールのグローバル変数に触れることができます。
モジュールは他のモジュールをインポートできます。 すべての import ステートメントをモジュール(またはスクリプト)の先頭に配置するのが通例ですが、必須ではありません。 インポートされたモジュール名は、インポートするモジュールのグローバルシンボルテーブルに配置されます。
モジュールからインポートするモジュールのシンボルテーブルに名前を直接インポートする import ステートメントの変形があります。 例えば:
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
これは、インポートが取得されるモジュール名をローカルシンボルテーブルに導入しません(したがって、この例では、fibo
は定義されていません)。
モジュールが定義するすべての名前をインポートするためのバリアントもあります。
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
これにより、アンダースコア(_
)で始まる名前を除くすべての名前がインポートされます。
一般に、モジュールまたはパッケージから*
をインポートする方法は、コードの読み取りが困難になることが多いため、嫌われていることに注意してください。 ただし、インタラクティブセッションでの入力を節約するために使用しても問題ありません。
モジュール名の後に 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つだけの場合は、 reload()を使用します。 reload(modulename)
。
6.1.1。 モジュールをスクリプトとして実行する
でPythonモジュールを実行する場合
python fibo.py <arguments>
モジュール内のコードは、インポートした場合と同じように実行されますが、__name__
は"__main__"
に設定されています。 つまり、モジュールの最後にこのコードを追加すると、次のようになります。
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
コマンドラインを解析するコードは、モジュールが「メイン」ファイルとして実行された場合にのみ実行されるため、ファイルをスクリプトおよびインポート可能なモジュールとして使用できるようにすることができます。
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
モジュールがインポートされた場合、コードは実行されません。
>>> import fibo
>>>
これは、モジュールに便利なユーザーインターフェイスを提供するため、またはテスト目的(スクリプトとしてモジュールを実行してテストスイートを実行する)のいずれかでよく使用されます。
6.1.2。 モジュール検索パス
spam
という名前のモジュールがインポートされると、インタープリターは最初にその名前の組み込みモジュールを検索します。 見つからない場合は、変数 sys.path で指定されたディレクトリのリストでspam.py
という名前のファイルを検索します。 sys.path は、次の場所から初期化されます。
- 入力スクリプトを含むディレクトリ(または現在のディレクトリ)。
- PYTHONPATH (シェル変数
PATH
と同じ構文のディレクトリ名のリスト)。 - インストールに依存するデフォルト。
初期化後、Pythonプログラムは sys.path を変更できます。 実行中のスクリプトを含むディレクトリは、検索パスの先頭、標準ライブラリパスの前に配置されます。 これは、ライブラリディレクトリ内の同じ名前のモジュールの代わりに、そのディレクトリ内のスクリプトがロードされることを意味します。 交換を意図していない限り、これはエラーです。 詳細については、セクション標準モジュールを参照してください。
6.1.3。 「コンパイルされた」Pythonファイル
多くの標準モジュールを使用する短いプログラムの起動時間の重要なスピードアップとして、spam.py
が見つかったディレクトリにspam.pyc
というファイルが存在する場合、これが想定されます。モジュールspam
のすでに「バイトコンパイルされた」バージョンを含むため。 spam.pyc
の作成に使用したspam.py
のバージョンの変更時刻は、spam.pyc
に記録され、.pyc
ファイルが一致しない場合は無視されます。
通常、spam.pyc
ファイルを作成するために何もする必要はありません。 spam.py
が正常にコンパイルされると、コンパイルされたバージョンをspam.pyc
に書き込もうとします。 この試みが失敗してもエラーではありません。 何らかの理由でファイルが完全に書き込まれなかった場合、結果のspam.pyc
ファイルは無効として認識されるため、後で無視されます。 spam.pyc
ファイルの内容はプラットフォームに依存しないため、Pythonモジュールディレクトリは異なるアーキテクチャのマシンで共有できます。
専門家のためのいくつかのヒント:
Pythonインタープリターが -O フラグで呼び出されると、最適化されたコードが生成され、
.pyo
ファイルに保存されます。 オプティマイザーは現在、あまり役に立ちません。 assert ステートメントのみを削除します。 -O を使用すると、 all bytecode が最適化されます。.pyc
ファイルは無視され、.py
ファイルは最適化されたバイトコードにコンパイルされます。2つの -O フラグをPythonインタープリター( -OO )に渡すと、バイトコードコンパイラーが最適化を実行し、まれにプログラムが誤動作する可能性があります。 現在、バイトコードから削除されるのは
__doc__
文字列のみであるため、.pyo
ファイルがよりコンパクトになります。 一部のプログラムはこれらを利用できることに依存している可能性があるため、このオプションは、自分が何をしているかを知っている場合にのみ使用してください。プログラムは、
.pyc
または.pyo
ファイルから読み取られた場合、.py
ファイルから読み取られた場合よりも高速に実行されません。.pyc
または.pyo
ファイルの方が速いのは、ファイルの読み込み速度だけです。コマンドラインで名前を指定してスクリプトを実行すると、スクリプトのバイトコードが
.pyc
または.pyo
ファイルに書き込まれることはありません。 したがって、スクリプトの起動時間は、そのコードの大部分をモジュールに移動し、そのモジュールをインポートする小さなブートストラップスクリプトを使用することで短縮できます。.pyc
または.pyo
ファイルにコマンドラインで直接名前を付けることもできます。同じモジュールのファイル
spam.py
なしで、spam.pyc
(または -O が使用されている場合はspam.pyo
)というファイルを持つことができます。 これを使用して、リバースエンジニアリングが適度に難しい形式でPythonコードのライブラリを配布できます。モジュール compileall は、ディレクトリ内のすべてのモジュールに対して
.pyc
ファイル(または -O が使用されている場合は.pyo
ファイル)を作成できます。
6.2。 標準モジュール
Pythonには、別のドキュメントであるPythonライブラリリファレンス(以下「ライブラリリファレンス」)で説明されている標準モジュールのライブラリが付属しています。 一部のモジュールはインタープリターに組み込まれています。 これらは、言語のコアの一部ではないが、効率のため、またはシステムコールなどのオペレーティングシステムプリミティブへのアクセスを提供するために組み込まれている操作へのアクセスを提供します。 このようなモジュールのセットは、基盤となるプラットフォームにも依存する構成オプションです。 たとえば、winreg
モジュールはWindowsシステムでのみ提供されます。 1つの特定のモジュールは注意に値します: sys 。これはすべてのPythonインタープリターに組み込まれています。 変数sys.ps1
およびsys.ps2
は、プライマリおよびセカンダリプロンプトとして使用される文字列を定義します。
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
Yuck!
C>
これらの2つの変数は、インタプリタが対話モードの場合にのみ定義されます。
変数sys.path
は、モジュールのインタープリターの検索パスを決定する文字列のリストです。 これは、環境変数 PYTHONPATH から、または PYTHONPATH が設定されていない場合は組み込みのデフォルトから取得されたデフォルトパスに初期化されます) 。 標準のリスト操作を使用して変更できます。
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
6.3。 NS dir() 関数
組み込み関数 dir()は、モジュールが定義する名前を見つけるために使用されます。 文字列のソートされたリストを返します。
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__',
'__stderr__', '__stdin__', '__stdout__', '_clear_type_cache',
'_current_frames', '_getframe', '_mercurial', 'api_version', 'argv',
'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',
'copyright', 'displayhook', 'dont_write_bytecode', 'exc_clear', 'exc_info',
'exc_traceback', 'exc_type', 'exc_value', 'excepthook', 'exec_prefix',
'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
'getrefcount', 'getsizeof', 'gettotalrefcount', 'gettrace', 'hexversion',
'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules',
'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
'py3kwarning', 'setcheckinterval', 'setdlopenflags', 'setprofile',
'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion',
'version', 'version_info', 'warnoptions']
引数がない場合、 dir()は、現在定義している名前を一覧表示します。
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', '__package__', 'a', 'fib', 'fibo', 'sys']
変数、モジュール、関数など、すべてのタイプの名前がリストされていることに注意してください。
dir()は、組み込み関数と変数の名前をリストしません。 それらのリストが必要な場合は、標準モジュール __ builtin __ で定義されています。
>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError',
'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError',
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning',
'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',
'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning',
'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__',
'__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring',
'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr',
'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright',
'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval',
'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset',
'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input',
'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license',
'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next',
'object', 'oct', 'open', 'ord', 'pow', 'print', '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']
6.4。 パッケージ
パッケージは、「点線のモジュール名」を使用して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
...
パッケージをインポートするとき、Pythonはsys.path
上のディレクトリを検索してパッケージサブディレクトリを探します。
__init__.py
ファイルは、Pythonがディレクトリをパッケージを含むものとして扱うようにするために必要です。 これは、string
などの一般的な名前のディレクトリが、後でモジュール検索パスで発生する有効なモジュールを意図せずに非表示にするのを防ぐために行われます。 最も単純なケースでは、__init__.py
は空のファイルにすることができますが、パッケージの初期化コードを実行したり、後で説明する__all__
変数を設定したりすることもできます。
パッケージのユーザーは、パッケージから個々のモジュールをインポートできます。次に例を示します。
import sound.effects.echo
これにより、サブモジュールsound.effects.echo
がロードされます。 フルネームで参照する必要があります。
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
サブモジュールをインポートする別の方法は次のとおりです。
from sound.effects import echo
これにより、サブモジュールecho
もロードされ、パッケージプレフィックスなしで使用できるようになるため、次のように使用できます。
echo.echofilter(input, output, delay=0.7, atten=4)
さらに別のバリエーションは、目的の関数または変数を直接インポートすることです。
from sound.effects.echo import echofilter
繰り返しますが、これはサブモジュールecho
をロードしますが、これによりその機能echofilter()
が直接利用可能になります。
echofilter(input, output, delay=0.7, atten=4)
from package import item
を使用する場合、アイテムはパッケージのサブモジュール(またはサブパッケージ)、または関数、クラス、変数など、パッケージで定義されている他の名前のいずれかであることに注意してください。 import
ステートメントは、最初にアイテムがパッケージで定義されているかどうかをテストします。 そうでない場合は、それがモジュールであると想定し、ロードを試みます。 見つからない場合は、ImportError
例外が発生します。
逆に、import item.subitem.subsubitem
のような構文を使用する場合、最後を除く各項目はパッケージである必要があります。 最後の項目はモジュールまたはパッケージにすることができますが、前の項目で定義されたクラス、関数、または変数にすることはできません。
6.4.1。 パッケージからのインポート*
ユーザーがfrom sound.effects import *
と書くとどうなりますか? 理想的には、これが何らかの形でファイルシステムに送信され、パッケージに存在するサブモジュールを見つけて、それらすべてをインポートすることを期待します。 これには長い時間がかかる可能性があり、サブモジュールをインポートすると、サブモジュールが明示的にインポートされた場合にのみ発生するはずの望ましくない副作用が発生する可能性があります。
唯一の解決策は、パッケージの作成者がパッケージの明示的なインデックスを提供することです。 import ステートメントは次の規則を使用します。パッケージの__init__.py
コードが__all__
という名前のリストを定義している場合、それは次の場合にインポートする必要があるモジュール名のリストと見なされます。 from package import *
が発生しました。 パッケージの新しいバージョンがリリースされたときにこのリストを最新の状態に保つのは、パッケージの作成者の責任です。 パッケージの作成者は、パッケージから*をインポートする用途が見当たらない場合は、サポートしないことを決定する場合もあります。 たとえば、ファイルsound/effects/__init__.py
には次のコードを含めることができます。
__all__ = ["echo", "surround", "reverse"]
これは、from sound.effects import *
がsound
パッケージの3つの名前付きサブモジュールをインポートすることを意味します。
__all__
が定義されていない場合、ステートメントfrom sound.effects import *
はパッケージsound.effects
から現在の名前空間にすべてのサブモジュールをインポートしませんしません。 パッケージsound.effects
がインポートされていることを確認し(__init__.py
で初期化コードを実行している可能性があります)、パッケージで定義されている名前をインポートするだけです。 これには、__init__.py
によって定義された(および明示的にロードされた)名前が含まれます。 また、以前の import ステートメントによって明示的にロードされたパッケージのサブモジュールも含まれます。 このコードを検討してください:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
この例では、echo
およびsurround
モジュールは、from...import
ステートメントの実行時にsound.effects
パッケージで定義されているため、現在の名前空間にインポートされます。 (これは、__all__
が定義されている場合にも機能します。)
特定のモジュールは、import *
を使用するときに特定のパターンに従う名前のみをエクスポートするように設計されていますが、それでも本番コードでは悪い習慣と見なされています。
from package import specific_submodule
を使用しても問題はないことを忘れないでください! 実際、インポートするモジュールが異なるパッケージの同じ名前のサブモジュールを使用する必要がない限り、これは推奨される表記法です。
6.4.2。 パッケージ内リファレンス
多くの場合、サブモジュールは相互に参照する必要があります。 たとえば、surround
モジュールはecho
モジュールを使用する場合があります。 実際、このような参照は非常に一般的であるため、 import ステートメントは、標準のモジュール検索パスを調べる前に、最初に含まれているパッケージを調べます。 したがって、surround
モジュールは単にimport echo
またはfrom echo import echofilter
を使用できます。 インポートされたモジュールが現在のパッケージ(現在のモジュールがサブモジュールであるパッケージ)に見つからない場合、 import ステートメントは指定された名前の最上位モジュールを探します。
パッケージがサブパッケージに構造化されている場合(例のsound
パッケージのように)、絶対インポートを使用して兄弟パッケージのサブモジュールを参照できます。 たとえば、モジュールsound.filters.vocoder
がsound.effects
パッケージのecho
モジュールを使用する必要がある場合、from sound.effects import echo
を使用できます。
Python 2.5以降では、上記の暗黙的な相対インポートに加えて、from module import name
形式のインポートステートメントを使用して明示的な相対インポートを記述できます。 これらの明示的な相対インポートでは、先頭のドットを使用して、相対インポートに関係する現在のパッケージと親パッケージを示します。 たとえば、surround
モジュールから、次を使用できます。
from . import echo
from .. import formats
from ..filters import equalizer
明示的および暗黙的な相対インポートはどちらも、現在のモジュールの名前に基づいていることに注意してください。 メインモジュールの名前は常に"__main__"
であるため、Pythonアプリケーションのメインモジュールとして使用することを目的としたモジュールは、常に絶対インポートを使用する必要があります。
6.4.3。 複数のディレクトリのパッケージ
パッケージは、もう1つの特別な属性__path__
をサポートします。 これは、そのファイル内のコードが実行される前に、パッケージの__init__.py
を保持するディレクトリの名前を含むリストに初期化されます。 この変数は変更できます。 これを行うと、パッケージに含まれるモジュールおよびサブパッケージの今後の検索に影響します。
この機能はあまり必要ありませんが、パッケージに含まれるモジュールのセットを拡張するために使用できます。
脚注
- 1
- 実際、関数定義は「実行される」「ステートメント」でもあります。 モジュールレベルの関数定義を実行すると、モジュールのグローバルシンボルテーブルに関数名が入力されます。