ところで、前回はインポートの形式として「from モジュール名 import *」を取り上げた。これはモジュールに含まれる全ての要素をローカルスコープに導入するものだ。この形式のインポートはパッケージについても以下のようにして同様に使える。ここでemailパッケージはPythonに標準で組み込まれているパッケージであり、電子メール関連の処理を行う複数のモジュールで構成されている。前回も述べたように、モジュールやパッケージに含まれているものを全て無鉄砲にインポートするのはよろしくないが、ここでは例としてこれを行っている。
from email import *
dir()
[Interactive]ウィンドウでの実行結果は次のようになる(改行は適宜挿入したもの)。
>>> from email import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__',
'base64mime', 'charset', 'encoders', 'errors', 'feedparser', 'generator',
'header', 'iterators', 'message', 'message_from_binary_file',
'message_from_bytes', 'message_from_file', 'message_from_string', 'mime',
'parser', 'quoprimime', 'utils']
これと同様なことを先ほどのmypackageについて行うとどうなるだろうか。これを([Interactive]ウィンドウの環境をリセットしてから)試した結果が以下だ。
>>> from mypackage import *
>>> dir() # mypackageが表示されない
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> mypackage # mypackageという名前は定義されていない
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'mypackage' is not defined
Pythonのチュートリアルドキュメントの「6.4.1. パッケージから * を import する」には「パッケージの __init__.py コードに __all__ という名前のリストが定義されていれば、 from package import * が現れたときに import すべきモジュール名のリストとして使う」「もしも __all__ が定義されていなければ、実行文 from sound.effects import * は、パッケージ sound.effects の全てのサブモジュールを現在の名前空間の中へ import しません」などと書いてある。
要するに、「from パッケージ import *」を実行したときに、パッケージ中のどのモジュールをインポートさせるかはパッケージの作者が明示的に指定をしなければならず、そのためには__init__.pyファイルの中で__all__変数にインポートするものを指定する必要があるということだ。
そこで、今まで空だった__init__.pyファイルを編集してみることにしよう。といっても、ここでは次の1行を追加するだけだ。
__all__ = ["mymodule1"]
__all__変数にはインポートさせたいモジュールを要素としたリストを代入する。以上のコードを書いてから、先ほどと同じことをしてみると次のようになる。
>>> from mypackage import *
hello from mypackage.mymodule1
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__',
'mymodule1']
ここでパッケージにmymodule2.pyファイルを追加してみよう。
mymodule2.pyファイルにはmymodule1.pyファイルと同様にインポート時にメッセージを表示し、同じくメッセージを表示するだけの関数fooを定義してある。
print("hello from module2 in mypackage")
def foo():
print("this is mypackage.mymodule2.foo speaking")
この状況で([Interactive]ウィンドウをリセットして)「from mypackage import *」を実行した結果を以下に示す。
>>> from mypackage import *
hello from mypackage.mymodule1 # 読み込まれたのはmymodule1のみ
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__',
'mymodule1']
>>> from mypackage import mymodule2 # mymodule2を明示的にインポート
hello from module2 in mypackage
>>> mymodule2.foo()
this is mypackage.mymodule2.foo speaking
__init__.pyファイルの__all__変数ではmymodule2モジュールをインポートするような記述は行っていないので、このパッケージにはmymodule1/mymodule2の2つのモジュールがあるにもかかわらず「from mypackage import *」でインポートされない。このように__init__.pyファイルで設定を行っておけば、自分のパッケージを誰か別の人が使うときに安心して(あるいは開発者が意図した形で)「from パッケージ名 import *」を実行できるようになる。
本稿の最後に、パッケージがパッケージを含んでいる場合についても簡単に見ておこう。
Copyright© Digital Advantage Corp. All Rights Reserved.