Pythonのimport文について
(2014/12/30)リンク先を修正し、サンプルコードの内容もPython 3に対応した。また、幾つかの内容を追加している。
import文とモジュール/パッケージ
import文では、指定した名前のPythonスクリプトやモジュール/パッケージを調べて、存在しない場合には例外(ImportError)を出し、存在する場合にはそのコードを実行する(中の変数や関数が読み込まれて利用可能となる)。モジュールはディレクトリ構造により階層を持つことができ、import文で指定した階層以下が読み込まれる。このように階層から成るモジュールの集まりはパッケージと呼ばれ、モジュールの階層は「.」により区切られる。
探索パス
モジュールの探索パスは、起動時(Pythonの外)には環境変数PYTHONPATH・実行中(Pythonの中)にはsys.path*1で読み書きできる。(2009/3/25)append()ではなく「sys.path.insert(0, '[ディレクトリ]')」で0番へのinsert()を行うと最も優先される。
import文のバリエーション
基本的な形
import sys
では「sys」モジュール以下の全ての変数や関数が「sys.」を先頭に付ける形で利用できるようになる。
import sys print (sys.argv)
標準で用意されていないモジュールを使用する場合、import文が失敗する(例外が発生する)可能性があるため、try節にimport文を書いてexcept節にエラー出力や終了の処理を記述する。
import sys try: import alsaaudio except: sys.exit ('Error: pyalsaaudio not installed')
(2014/12/30)モジュール名はコンマ区切りにして同時に複数記述できる。
import sys, os
モジュール名をたどらないで使用する
「xml.parsers.expat」のように複数の階層になっているもの(サブモジュール)を上の形のimport文で使用すると、中の関数などの名前をたどる際に長くなるがfrom [モジュール名] import [使用したい変数や関数]
の形で書くことで、モジュール名の部分を飛ばして使用することができる。例えば
import xml.parsers.expat
p = xml.parsers.expat.ParserCreate ()
は
from xml.parsers.expat import ParserCreate p = ParserCreate ()
と書くことができる。この場合の「import」の後ろの部分には「全て」を示す「*」も指定できる*2。モジュールの集まりであるパッケージにおける「*」の指定についてはチュートリアルも参照。
ただし、「sys」「os」などでこの形の指定をした場合、必ずしもPythonのコードが読みやすくなるとは言えず*3、「os」に至っては「*」指定をすると組み込み関数open()がos.open()で隠蔽されるという問題もあるため、避けたほうがよい。
別名で使用
上の「from xxx import xxx」の書き方を使用すると、モジュール側の変数や関数の名前をそのまま利用できるが、後ろに「as [名前]」を付けることで、別の名前で使用することができる。下の例では関数gettext.gettext()を_()として使用できるようにしている。
from gettext import gettext as _
(2014/12/30)この例の場合はgettext.install()を用いるのが便利。
Pythonの動作に関するimport文
(2014/12/30)「from __future__ import [機能を示す文字列]」の形のimport文を実行することで、Pythonの構文解析の動作を(新しいものに)変えることのできる場合がある。例えば、バージョン2.6以上のPython 2でfrom __future__ import print_function
を実行すると、Python 3と同様のprint()関数が利用できるようになる(Python 3で実行しても特にエラーになったりはしない)。代わりにprint文は使えなくなる。
簡単な例
下の2つのコードを同じディレクトリに配置するか、1つ目のコードを環境変数PYTHONPATHのディレクトリに配置してから2つ目のコードを実行する。ファイル名: ${PYTHONPATH}/foo.py
AAA = 12345 def func (a): return a def func2 (a, b): return '{0} and {1}'.format (a, b) if __name__ != '__main__': print ('** imported foo.py **')
[任意]ファイル名: importtest.py
#! /usr/bin/python # -*- coding: utf-8 -*- from __future__ import print_function # foo.pyやモジュールfooの中の関数や変数に「foo.」付きでアクセス print ('import foo') import foo print ('foo.AAA: {0}'.format (foo.AAA)) print ('foo.func("test"): {0}'.format (foo.func ('test'))) # 「foo.」なしではアクセスできないのを実験 try: print ('AAA: {0}'.format (AAA)) except NameError as e: print ('NameError({0})'.format (e)) try: print ('func2("You", "I"): {0}\n'.format (func2 ('You', 'I'))) except NameError as e: print ('NameError({0})\n'.format (e)) # funcとfunc2だけを「foo.」なしで使用する print ('from foo import func, func2') from foo import func, func2 print ('func("TEST"): {0}'.format (func ('TEST'))) print ('func2("drag", "drop"): {0}\n'.format (func2 ('drag', 'drop'))) # foo以下の全てを「foo.」なしで使用する print ('from foo import *') from foo import * print ('AAA: {0}\n'.format (AAA)) # 別名(BBB)でAAAを使用 print ('from foo import AAA as BBB') from foo import AAA as BBB print ('BBB: {0}'.format (BBB))
下は実行結果。
import foo ** imported foo.py ** foo.AAA: 12345 foo.func("test"): test NameError(name 'AAA' is not defined) NameError(name 'func2' is not defined) from foo import func, func2 func("TEST"): TEST func2("drag", "drop"): drag and drop from foo import * AAA: 12345 from foo import AAA as BBB BBB: 12345
「** imported foo.py **」は最初の1回しか出ていないが、今回の例では同じファイルが繰り返しimportされているためで、「from」を使用したimport文でも、コード中で初回のimportであれば出力される。下はPythonのシェルでのテスト。
$ PYTHONPATH=${PYTHONPATH}:[foo.pyのあるディレクトリ] python (中略) >>> from foo import func ** imported foo.py ** >>>
また、foo.pyで__name__の値によって処理を分岐しているが、直接foo.pyを実行した場合にはこの値が「__main__」となり、importにより実行されたときにはその名前となる。上のfoo.pyの最後に
print "__name__: " + __name__
を追加すると、出力は
import foo ** imported foo.py ** __name__: foo foo.AAA: 12345 (以下略)
のようになる。
参考URL: