pythonモジュールのロードとパス検索の理解

5767 ワード

参照自己理解pythonモジュールのロードとパス検索
基礎概念
  • moduleモジュール、1つのpyファイルまたは他のファイル形式で存在するインポート可能なものが1つのモジュール
  • パッケージ、initファイルを含むフォルダ
  • relative path対向経路、あるディレクトリに対する経路
  • absolute path絶対経路、全経路
  • 経路検索python解釈器導入されたパケットまたはモジュールを検索
  • python実行時にパッケージとモジュールを検索する方法
    pythonモジュールの実行
    pythonは1つのファイルを実行し、実行方法が絶対パスであろうと相対パスであろうと、解釈器はファイルが存在するディレクトリをシステム検索パス、すなわちsys.pathこのlistの中に加え、sys.pathまたシステムのpython環境変数によって決定する.
    #test.py
    import os
    import sys
    print sys.path[0]
    

    このファイルを実行します.
    python test.py
    python /Users/x/workspace/blog-code/p2016_05_28_python_path_find
    test.py
    

    相対パスと絶対パスは同じ結果を出力します.test.pyが存在するフォルダはいずれもsys.pathのトップに追加されますが、ここがトップ、つまりインデックスが0の位置であることに注意してください.
    インタプリタ実行時には、まず探索built-in module、つまりインタプリタ探索モジュールが最初に探索するのはbuilt-in moduleであり、次に探索sys.pathに含まれる経路が探索される.このような検索順序は、同じ名前のパッケージまたはモジュールが隠されているという問題を引き起こします.
    ├── os.py
    ├── test2.py
    ├── redis.py
    
    #test2.py
    import os
    from redis import Redis
    

    test 2を実行する.pyファイル
    Traceback (most recent call last):
        File "/Users/x/workspace/blog-code/p2016_05_28_python_path_find/test2.py", line 1, in 
            from redis import Redis
    ImportError: cannot import name Redis
    

    OSはbuilt-in moduleであるため、同じディレクトリの下に同じ名前のモジュールがある場合でも、解釈器は正しいosモジュールを見つけることができ、redisはサードパーティのモジュールに属し、デフォルトのインストール場所はpython環境変数のsite-packagesであり、解釈器が起動するとこのディレクトリがsysに追加されます.pathは、sys.pathのトップであるため,ローカルのredisが導入される.
    インタラクティブ実行環境
    インタラクティブ実行環境に入ると、解釈器は自動的に現在のディレクトリをsysに追加する.path、このとき現在のディレクトリはsysに相対的な経路で現れる.パス:
    >>> import os.path
    >>> import sys
    >>> os.path.abspath(sys.path[0])
    '/Users/x/workspace/blog-code'
    >>>
    

    それ以外は、1つのファイルを実行するのと同じです.
    file変数の理解
    python doc: file is the pathname of the file from which the module was loaded, if it was loaded from a file. モジュールがファイルからロードされている場合、fileはモジュールのパス名です.
    名前の通り、モジュールがファイルとして現れるとfileはモジュールファイルのパス名を指し、相対パスでfileを実行するのは相対パスであり、絶対パスでfileを実行するのは絶対パスである.
    #test.py
    print __file__
    

    相対パス実行{{そうたいぱす:じっこう}}
    python test3.py
    test3.py
    

    絶対パス実行{{ぜったいぱす:じっこう}}
    python /Users/x/workspace/blog-code/p2016_05_28_python_path_find/test3.py
    

    fileが毎回モジュールの正確な位置を正確に得ることを保証するために、絶対パスをもう一度取ることが望ましい.
    os.path.abspath(__file__)
    

    インタラクティブshellに入るとfileを入力するとエラーが表示されます
    >>> __file__
    Traceback (most recent call last):
        File "", line 1, in 
    NameError: name '__file__' is not defined
    

    これは、現在のインタラクティブshellの実行がファイル形式でロードされていないため、__file__という属性は存在しないからである.
    変数sys.argv[0]sys.argv[0]メインエントリ実行ファイルを取得するための変数です.
    A sample
    #test.py
    import sys
    print __file__
    print sys.argv[0]
    

    以上の2つのprintは、プライマリ実行ファイルとfileが属するモジュールが同じであるため、同じ結果を出力します.エントリファイルを変更すると、違いが現れます.
    A sample
    #test.py
    import sys
    print __file__
    print sys.argv[0]
    #test2.py
    import test
    

    test 2を実行する.py
    /Users/x/workspace/blog-code/p2016_05_28_python_path_find/child/test.py #__file__
    test2.py #sys.argv[0]
    

    総じて、sys.argv[0]はエントリ実行ファイルを取得するパスであり、__file__は任意のモジュールファイルを取得するパスである.
    sys.modulesの役割
    pythonがsysである以上pathでモジュールを検索した場合、ロードされたモジュールはどこに保存されますか?答えはsysだmodulesは、ロードされたモジュールを格納する場所です.モジュールがロードされるとpythonはこのモジュールをsysに追加する.modulesでは、次回のロードで使用できます.これにより、モジュールの導入を加速させ、キャッシュの役割を果たすことができます.
    >>> import sys
    >>> sys.modules['tornado']
    Traceback (most recent call last):
        File "", line 1, in 
    KeyError: 'tornado'
    >>> import tornado
    >>> sys.modules['tornado']
    
    

    python解釈器が起動するとbuilt-in moduleに予めロードされ、sys.modules検証.
    >>> sys.modules['os']
    
    >>>
    

    モジュールのパスの取得
    sysを借りるmodulesとfileでは、ロードされたすべてのモジュールディレクトリとパスを動的に取得できます.
    >>> import os
    >>> os.path.realpath(sys.modules['os'].__file__)
    '/Users/x/python_dev/lib/python2.7/os.pyc'
    >>> import tornado
    >>> os.path.realpath(sys.modules['tornado'].__file__)
    '/Users/x/python_dev/lib/python2.7/site-packages/tornado/__init__.pyc'
    
    def get_module_dir(name):
            path = getattr(sys.modules[name], '__file__', None)
            if not path
                    raise AttributeError('module %s has not attribute __file__'%name)
            return os.path.dirname(os.path.abspath(path))
    

    from文とimport文
    pythonがモジュールを検索して保存する方法がわかりました.pythonモジュールのインポートについてお話しします.
    インポート順序
    pythonパッケージのインポート順序は
        -->     -- > sys.path
    

    したがって、同名のパケットは、システムパケットの優先度が最も高い>同ディレクトリ>sys.path、このような違いがあるのは、現在の実行ディレクトリがsysに優先的に加入するからである.Pathのトップ.
    インポート時に実行
    モジュールをインポートすると、グローバル変数、クラス、関数の宣言など、モジュールの最上位変数が実行されます.したがって、モジュールを作成するときは、副作用(関数の呼び出し)を除去することに注意してください.
    import文とfrom文
    importに含まれるのは、package、packageのモジュール、モジュールの変数です.影響importの属性は__all____all__リストであり、packageでfrom package import *で導出されたモジュール、すなわち__all__で定義されたモジュールのみfrom package import *で導出されることに影響を与えることができる.
    summary
    pythonのモジュール導入、ロードと検索にはまだまだ言えることがたくさんありますが、特にダイナミックimportは、pythonのキーワードがimportに対応しているので、興味のある方は検討してみてくださいtornado.utilモジュール下のimport_object.