[T.I.L]importコマンドは、パッケージとモジュールを検索します.


Pythonでimportを実行し、3つの場所を順にチェックしてモジュールまたはパッケージを検索します.
  • sys.modules
  • built-in modules
  • sys.path
  • sys.modules

  • には、すでに輸入されたモジュールとパッケージが格納されています.
    👉 インポートしたモジュールとパッケージは二度と見つかりません.
    👉 新しくインポートしたモジュールとパッケージはsysです.モジュールに見つかりません.
  • 辞書状態からなる.
    👉 {モジュール名:パス}
  • built-in modules

  • はPythonが提供する公式ライブラリです.
  • sys.path

  • list形式で存在し、文字列要素(パス)を有する.
  • Pythonは、パスを1つずつチェックし、パスにインポートするパッケージがパスにあるかどうかを決定します.
  • Question:sysもインポートする必要があるモジュールですが、Pythonはどのようにsysモジュールの位置を見つけますか?
    👉 Sysモジュールは既にPythonに内蔵されているモジュールの一つです.すなわち、組み込みモジュールに存在するためsysをインポートできます.

    Absolute path vs Relative path

    └── my_app
        ├── main.py
        ├── package1
        │   ├── module1.py
        │   └── module2.py
        └── package2
            ├── __init__.py
            ├── module3.py
            ├── module4.py
            └── subpackage1
                └── module5.py                  
    my appというプロジェクトで、package 1とpackage 2というファイルパスです.
    Absolute path(絶対パス)は、その名の通りパス全体を指す.
    Subpackage 1パッケージの下にモジュール「module 5」のfunction 2という関数をインポートするには、次のようにインポートします.
    from package2.subpackage1.module5 import function2
    パスの開始点は、最上位ディレクトリmy appから始まります.
    つまり、経路の開始から終了までです.
    このように導入すると経路が長くなります.😩
    だから存在する概念は相対経路である.
    相対パスは、インポート位置に対するパスです.
    たとえば、package 2のmodule 3からpackage 2のclass 1とpackage 2のサブパッケージsubpackage 1のmodule 5のfunction 2関数をインポートしようとすると、次の操作ができます.
    # package2/module3.py
     
    from . import class1
    from .subpackage1.module5 import function2
  • dot .import宣言ファイルの現在位置を指します.
  • dot .. は、現在の場所から親ディレクトリへのパスです.
  • *注意)Relative pathの利点は、宣言するパスの長さを減らすことですが、難点は紛らわしいことです.また、ファイルの場所が変更された場合、パスの場所も変更する必要があります.

    計算機パッケージの作成



    上の図面と一緒に「calcuator」というパッケージmainを作りますpyは、以下に示すように、add and multiplyというモジュールを相対パスにインポートします.
    from .calculator.add_and_multiply import add_and_multiply
     
    if __name__ == '__main__':
        print(add_and_multiply(1,2))
        
    >>>ImportError: attempted relative import with no known parent package
    ImportErrorが表示されます.
    if __name__ == '__main__':
    名前のコードが使用され、nameという変数はファイル名に相当し、現在実行されているファイルではmainとなります.つまり「独自のモジュールを単独で実行する場合」です.
    Google検索結果:
    python解釈器は、importに対するモジュールの位置を決定する際にname属性によって決定される.pythonファイルを直接実行する場合、name=「main」はもちろん(?)Pythonインタプリタがmainというモジュールの位置を特定できないため、エラーが発生しました.
    これは、実行中のモジュールの名前がmainになり、インポートされた他のモジュールがそのモジュールの名前になることを意味します.
    +name=="main"は実行主体としてのモジュールなので、絶対パスを書かなければなりません.後で...
    Pythonでは,モジュールを単独で実行する際に相対アドレスを書くのではなく,絶対アドレスを書く.(原因不明😂)
    👉 直接実行すると、絶対パスimportが実行され、そうでない場合(=パッケージ内部import)、相対パスimportが実行されます.
    上記のコードを正常に動作させる場合は、相対パスを絶対パスに変換します.計算機の前の点.取ればいいです.このようなことが発生するため、メインモジュールで他のモジュールをインポートする場合は、絶対パスに書き込む必要があります.ただしimportのモジュールは直接実行するモジュールではないので、相対パスを書くことができます.
    #add_and_mulitply.py
    
    1) from .multiplication import multiply 
    2) from calculator.multiplication import multiply
     
    def add_and_multiply(a,b):
        return multiply(a,b) + (a+b)
    上のコードはadd and multiplyモジュールのコードです.このモジュールでは、直接実行するのではなくmainモジュールからインポートされるモジュールなので、相対パスインポートを使用するか、絶対パス書き込みを使用することができます.

    )initを追加します。pyのロール


    __init__.pyファイルは、ディレクトリがパッケージの一部であることをユーザーに伝えるか、名前でパッケージを初期化することができます.

    calpkgパッケージには、ジオメトリと操作モジュールが含まれています.
    mainモジュールからcalpkgパッケージとしてモジュールをインポートしてロードする場合は、次の手順に従います.
    Initファイルに次のコードを記述すればよい.
    #(main.py도 calpkg 안에 속해있다.)
    #__init__.py
    
    from . import operation     
    from . import geometry     
    #main.py
    
    import calcpkg    # calcpkg 패키지만 가져옴
     
    print(calcpkg.operation.add(10, 20))    # operation 모듈의 add 함수 사용
    print(calcpkg.geometry.triangle_area(30, 40))    # geometry 모듈의 triangle_area 함수 사용
    calpkgならoperation.addではなくaddのように関数名を使用したい場合は!
    # 현재 패키지의 operation, geometry 모듈에서 각 함수를 가져옴
    # 현재 패키지(calcpkg)라는 것을 나타내기 위해 모듈 앞에 .을 붙인다.
    
    #__init__.py
    
    from .operation import add, mul
    from .geometry import triangle_area, rectangle_area
    
    あるいは、すべての関数をインポートしたい場合は、以下のようにすることができます.
    from .operation import *
    from .geometry import *
    *を関数、変数、またはクラスに制限する場合は、allに挿入したい関数、変数、およびクラスを以下に示します.
    #__init__.py
    
    # calcpkg 패키지에서 add, triangle_area 함수만 공개
    
    __all__ = ['add', 'triangle_area']    
     
    from .operation import *     
    from .geometry import *    
    では、メインモジュールには、次のimportgodaus ehlsekが含まれます.
    from calcpkg import *    # calcpkg 패키지의 모든 변수, 함수, 클래스를 가져옴
     
    print(add(10, 20))    # add 함수는 공개되어 있으므로 사용할 수 있음
    print(mul(10, 20))    # 에러: mul 함수는 공개되어 있지 않으므로 사용할 수 없음
     
    print(triangle_area(30, 40))    # triangle_area 함수는 공개되어 있으므로 사용할 수 있음
    print(rectangle_area(30, 40))   # 에러: rectangle_area 함수는 공개되어 있으므로 사용할 수 있음