メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2008年2月17日日曜日

[Python][お勉強] Python入門(38) - パッケージ

今日はパッケージから。


パッケージとは
Pythonで言う、「パッケージ」とは、通常、sysモジュールのpath属性に記録されているサーチバスのディレクトリの__init__.pyファイルが置いてある「サブディレクトリ」のこと。

また、ディレクトリパスを指定してインポートすることを「パッケージインポート」と呼ぶ。



パッケージインポートしてみる。

パッケージインポートするには、モジュールの「パス」を指定する。
「パス」の指定には、ディレクトリセパレータに「.」(ドット)を使用する。

早速やってみる。
まず、カレントディレクトリに、dir1ディレクトリを作成。


$ mkdir dir1
$ ls
dir1/
 


で、dir1以下に行き、空の__init__.pyファイルを作成。

$ cd dir1
$ touch __init__.py
 


で、へぼモジュールを作成。中身はこんな感じ。

$ cat hebo.py
print "hebo loading"

def hebohebo(x):
print "hebohebo call(", x, ")"

print "hebo done"
 


そしたら、最初のディレクトリに戻って、

$ cd ..
 

pythonを起動しトップレベルを開く。でインポートしてみる。

$ python
Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dir1.hebo
hebo loading
hebo done
>>> dir1.hebo.hebohebo("hebo")
hebohebo call( hebo )
>>>
 


できた。

この場合、パッケージは「サブディレクトリ」であるdir1にあたる。


__init__.pyファイル
パッケージインポートする場合、「サブディレクトリ」には必ず__init__.pyファイルを置かなければならない。そうしないとインポートが行えない。

ということで、__init__.pyファイルを削除してインポートしてみる。

$ rm dir1/__init__.*
$ python
Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dir1.hebo
Traceback (most recent call last):
File "", line 1, in ?
ImportError: No module named dir1.hebo
>>>
 

怒られた。


__init__.pyファイルは普通のモジュールファイルで、Pythonのコードを中に書き込むことができる。
最低限、空でも良いので「サブディレクトリ」には__init__.pyファイルが存在しないとインポートできない。

__init__.pyファイルは通常パッケージインポートの際の初期化処理に利用される。つまり、__init__.pyファイルはパッケージインポートの際、中のコードが実行される。



パッケージの名前空間
パッケージインポートを行うと、指定されたディレクトリパスのディレクトリ毎に名前空間が作成される。

dir1.hebo
 

とあった場合には、dir1の名前空間と、heboモジュールの名前空間がネストされた状態で作成される。
dir1の名前空間には、ディレクトリdir1の__init__.pyで代入処理が行われた変数が全て属する。

ということで、またもややってみる。
__init__.pyの中で、Xという名の変数を用意。

$ cat dir1/__init__.py
X=100
 

で、インポートして変数Xにアクセスしてみる。

$ python
Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dir1.hebo
hebo loading
hebo done
>>> dir1.X
100
>>>
 

ほんとだー。


__all__属性

from XXXX import *
 

という形でパッケージインポートされた際、どのパッケージをコピー対象とするかを__all__属性を使用して設定することができる。
__all__属性を使用しなかった場合は、インポートされるのは__init__.pyで作成された変数のみ。
サブディレクトリが自動的にインポートされるということはない。

これもまたやってみる。
まずは、__all__属性未指定。

$ cat dir1/__init__.py
X=100
 

で、fromステートメントの*版でインポート。

$ python
Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from dir1 import *
>>> import sys
>>> sys.modules.keys()
['dir1', 'copy_reg', '__main__', 'site', '__builtin__', 'encodings', 'posixpath',
'encodings.codecs', 'os.path', '_codecs', 'encodings.exceptions', 'stat', 'zipimport',
'warnings', 'encodings.types', 'UserDict', 'encodings.utf_8', 'sys', 'codecs',
'readline', 'types', 'signal', 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'os']
>>>
 

__all__属性未指定時はこんな感じになっている。
こんどは__all__属性を指定してみる。
__init__.pyはこんな感じ。

$ cat dir1/__init__.py
X=100
__all__ = ["hebo"]
 


早速インポート。

$ python
Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from dir1 import *
hebo loading
hebo done
>>> import sys
>>> sys.modules.keys()
['dir1', 'copy_reg', '__main__', 'site', '__builtin__', 'encodings', 'posixpath',
'encodings.codecs', 'os.path', '_codecs', 'encodings.exceptions', 'dir1.hebo',
'stat', 'zipimport', 'warnings', 'encodings.types', 'UserDict', 'encodings.utf_8',
'sys', 'codecs', 'readline', 'types', 'signal', 'linecache', 'posix', 'encodings.aliases',
'exceptions', 'os']
>>>
 

こんどはdir1.heboも入っている。



ふーん。

おしまい。
.

0 コメント: