[セットトップ]pythonモジュールおよびパッケージのインポート

8001 ワード

一.module
通常モジュールは1つのファイルで、importを直接使用してインポートすればいいです.moduleとして使用できるファイルタイプは「.py」、「.pyo」、「.pyc」、「.pyd」、「.so」、「.dll」です.
二.packageでは、通常、パッケージは常にディレクトリであり、importインポートパッケージ、またはfrom+importを使用してパッケージのモジュールの一部をインポートできます.パッケージディレクトリの下にある最初のファイルは__です.init__.py.次に、一部のモジュールファイルとサブディレクトリがあります.サブディレクトリにも__がある場合はinit__.pyでは、このパッケージのサブパッケージです.
 
 
一.モジュールimport文を使用してソースファイルをモジュールとしてインポートできます.例:
# file : spam.py
a = 37                    #     
def foo:                  #     
    print "I'm foo"
class bar:                #    
    def grok(self):
        print "I'm bar.grok"
b = bar()                 #       

import spam文を使用すると、このファイルをモジュールとしてインポートできます.システムはモジュールを導入する時、以下の3つのことをします:1.ソースファイルで定義されたオブジェクトに名前空間を作成し、モジュールで定義された関数および変数にアクセスできます.
2.新しく作成した名前空間でソースファイルを実行する.
3.モジュールの名前空間を参照するソースファイルという名前のオブジェクトを作成します.これにより、モジュール内の関数および変数にアクセスできます.たとえば、次のようになります.
 import spam           #         spam
 print spam.a          #      spam    
 spam.foo()
 c = spam.bar()

モジュール名をカンマで分割すると、複数のモジュールを同時にインポートできます.
import socket, os, regex
モジュールのインポート時にasキーを使用して、モジュールの参照オブジェクトの名前を変更できます.
import os as system
import socket as net, thread as threads
system.chdir("..")
net.gethostname()
from文を使用して、モジュール内のオブジェクトを現在の名前空間に直接インポートすることができる.from文は、モジュール名空間への参照オブジェクトを作成するのではなく、インポートされたモジュールの1つ以上のオブジェクトを現在の名前空間に直接挿入します.
from socket import gethostname #  gethostname        
print gethostname()            #     
socket.gethostname()           #     NameError: socket

from文はカンマで分割されたオブジェクトをサポートします.また、モジュールの下線の先頭を除くすべてのオブジェクトをアスタリスク(*)で表すこともできます.
from socket import gethostname, socket
from socket import *   #              
ただし、モジュールが定義されている場合はリスト_all__,from module import*文は__しかインポートできませんall__リストに表示されます.
# module: foo.py
__all__ = [ 'bar', 'spam' ]     #      `*`        

また、asはfromと連携して使用することもできます.
from socket import gethostname as hostname
h = hostname()

import文は、プログラムの任意の場所で使用できます.プログラムに同じモジュールを複数回インポートできますが、モジュール内のコード*は、モジュールが最初にインポートされたときにのみ実行されます.後のimport文は、モジュール名空間への参照を簡単に作成するだけです.sys.modules辞書には、インポートされたモジュールのすべてのモジュール名からモジュールオブジェクトへのマッピングが保存されています.この辞書は、import文を使用してモジュールの最新コピーをインポートする必要があるかどうかを決定するために使用される.from module import*文は、1つのモジュールの最上位レベルにのみ使用できます.*特に注意*:役割ドメインの競合のため、from文は関数で使用できません.
各モジュールには__があります.name__ モジュール名の内容を持つ文字列です.最上位レベルのモジュール名は_main__ .コマンドラインまたはインタラクションモードでプログラムが実行されます.main__ モジュール内部利用_name__プロパティでは、次のように、同じプログラムを異なる場合(単独で実行またはインポート)に異なる動作を持たせることができます.
#             

if __name__ == '__main__':
      # Yes
      statements
else:
      # No (         )
      statements 

モジュール検索パス
モジュールをインポートすると、解釈器はsysを検索する.pathリストで、このリストには一連のディレクトリが保存されています.典型的なsys.pathリストの値:
Linux:
['', '/usr/local/lib/python2.0',
     '/usr/local/lib/python2.0/plat-sunos5',
     '/usr/local/lib/python2.0/lib-tk',
     '/usr/local/lib/python2.0/lib-dynload',
     '/usr/local/lib/python2.0/site-packages']
Windows:
['', 'C:\\WINDOWS\\system32\\python24.zip', 'C:\\Documents and Settings\\weizhong', 'C:\\Python24\\DLLs', 'C:\\Python24\\lib', 'C:\\Python24\\lib\\plat-win', 'C:\\Python24\\lib\\lib-tk', 'C:\\Python24\\Lib\\site-packages\\pythonwin', 'C:\\Python24', 'C:\\Python24\\lib\\site-packages', 'C:\\Python24\\lib\\site-packages\\win32', 'C:\\Python24\\lib\\site-packages\\win32\\lib', 'C:\\Python24\\lib\\site-packages\\wx-2.6-msw-unicode']
空の文字列は現在のディレクトリを表します.新しい検索パスを追加するには、このリストにこのパスを追加するだけです.
 
モジュールのインポートとアセンブリ
これまで本章で紹介するモジュールはすべてPythonソースコードを含むテキストファイルである.ただし、モジュールはこれに限らず、import文でインポートできるモジュールには以下の4種類があります.
•Pythonで書かれたプログラム(.pyファイル)
•CまたはC++拡張(共有ライブラリまたはDLLファイルにコンパイル済み)
•パッケージ(複数のモジュールを含む)
•組み込みモジュール(Cを使用してPythonインタプリタに作成されリンクされている)
クエリモジュールfooの場合、解釈器はsysに従う.pathリストのディレクトリの順序は、次のファイルを検索します(ディレクトリもファイルの1つです).
1.パッケージとして定義されたディレクトリfoo
2.foo.so, foomodule.so, foomodule.sl、またはfoomodule.dll(コンパイル拡張)
3.foo.pyo(-Oまたは-Oオプションを使用する場合のみ)
4.foo.pyc
5.foo.py
 
はい.pyファイルは、モジュールが初めてインポートすると、バイトコードとしてアセンブリされ、バイトコードを同名に書き込む.pycファイルその後のインポート操作はそのまま読み出す.pycファイルではありません.pyファイル(.pyファイルの変更日が更新されない限り.pycファイルは再生成されます)解釈器が-Oオプションを使用する場合、拡張子は.pyoの同名ファイルが使用されます.pyoファイルの内容は行番号、断言、その他のデバッグ情報のバイトコードを除くが、体積が小さく、実行速度が速い.-Oの代わりに-Oオプションを使用すると、ドキュメント文字列も作成されます.pyoファイルの場合も無視されます.
もしsys.pathが提供するすべてのパスが検索に失敗すると、解釈器は組み込みモジュールで検索を継続し、再び失敗するとImportError異常を引き起こす.
.pycと.pyoファイルのアセンブリは、import文が実行する場合にのみ行う.
import文がファイルを検索する場合、ファイル名は大文字と小文字に敏感です.ファイルシステムの大文字小文字に敏感でないシステムでもそうである(Windowsなど).これにより、import fooはファイルfooのみをインポートする.pyはFOOではありません.PY.
 
モジュールの再インポート
既にimport文でインポートするモジュールが更新された場合、組み込み関数reload()は更新後のモジュールコードを再インポートして実行することができる.パラメータとしてモジュールオブジェクトが必要です.例:
import foo
... some code ...
reload(foo)#fooを再インポート
reload()の実行後のモジュールに対する操作では、新しいインポートコードが使用されますが、reload()は古いモジュールで作成されたオブジェクトを更新しないため、新しい古いバージョンのオブジェクトが共存する可能性があります.*注意*CまたはC++でコンパイルされたモジュールはreload()関数で再インポートできません.デバッグと開発の過程でない限りreload()関数を使用しないという原則を覚えておいてください.
 
2.パッケージ
複数の密接なモジュールは、メンテナンスと使用を容易にするためにパッケージに編成する必要があります.このテクノロジーは、名前空間の衝突を効果的に回避します.パッケージ名のフォルダを作成し、そのフォルダの下に__を作成します.init__.pyファイルはパッケージを定義します.必要に応じて、このフォルダの下にリソースファイル、コンパイル済み拡張子、サブパッケージを保存できます.たとえば、1つのパッケージには次の構造があります.
Graphics/
      __init__.py
      Primitive/
         __init__.py
         lines.py
         fill.py
         text.py
         ...
      Graph2d/
         __init__.py
         plot2d.py
         ...
      Graph3d/
         __init__.py
         plot3d.py
         ...
      Formats/
         __init__.py
         gif.py
         png.py
         tiff.py
         jpeg.py
 
import文は、次の方法でパッケージ内のモジュールをインポートします.
 import Graphics.Primitive.fill #    Graphics.Primitive.fill,           ,   Graphics.Primitive.fill.floodfill(img,x,y,color).
 from Graphics.Primitive import fill#     fill ,    fill.             ,   fill.floodfill(img,x,y,color).
 from Graphics.Primitive.fill import floodfill #    fill ,    floodfill        ,          ,   floodfill(img,x,y,color).
パッケージのどの部分がインポートされても、ファイル_init__.pyのコードが実行されます.このファイルの内容は空にできますが、通常はパッケージの初期化コードを格納するために使用されます.インポートプロセスで遭遇したすべての_init__.pyファイルはすべて実行されます.だからimport Graphics.Primitive.Fill文はGraphicsとPrimitiveフォルダの下の__を順番に実行します.init__.pyファイル
次の文は曖昧です.
from Graphics.Primitive import * 
この文の本来の意図はGraphicsをPrimitiveパッケージの下のすべてのモジュールが現在の名前空間にインポートされます.しかし、プラットフォーム間でファイル名のルールが異なる(例えば、大文字と小文字の敏感な問題)ため、Pythonはどのモジュールが導入されるべきかを正確に判定することができない.この文はGraphicsとPrimitiveフォルダの下の__のみを順番に実行します.init__.pyファイルこの問題を解決するには、Primitiveフォルダの下にあるはずです.init__.pyでallという名前のリストを定義します.たとえば、次のようにします.
# Graphics/Primitive/__init__.py
__all__ = ["lines","text","fill",...]
このように、上の文はリスト内のすべてのモジュールにインポートすることができる.
次の文はGraphicsディレクトリの下の__のみを実行します.init__.pyファイルは、モジュールをインポートしません:
import Graphics
Graphics.Primitive.fill.floodfill(img,x,y,color)  #   !

ただし、import Graphics文はGraphicsディレクトリの下の__を実行します.init__..pyファイルでは、次のような方法でこの問題を解決できます.
# Graphics/__init__.py
import Primitive, Graph2d, Graph3d
# Graphics/Primitive/__init__.py
import lines, fill, text, ...
このようにimport Graphics文はすべてのサブモジュールをインポートすることができる(これらのモジュールの属性にフルネームでのみアクセスできる).
sys....modules
sys.pathにはmoduleの検索パスが含まれています.
sys.modulesには、現在loadされているすべてのmodulesのdict(builtinのmodulesが含まれている)が含まれています.