Python-パッケージ、モジュールパス
9706 ワード
1. sys.モジュールとシステム.pathの違い
Pythonはimport時にsearch順を以下のように設定します. sys.modules built-in modules sys.path sys.モジュールは単純な辞書形式です.インポートされたモジュールやパッケージを格納している場所、新しくインポートされたモジュールなどが見つかりません.下記のコードを確認すれば確認できますが、まだまだたくさんあります.
sys.pathは基本的にlistのstring要素を有する.次のコードを見れば理解できます.
私たちはすでに上で違いを見ましたがsys.モジュールはモジュールの集合、sysです.pathには経路の違いがあります.
システム.modulesはdictの形式でsysです.pathにも違いがあり、リスト内のstringの形式があります.
sys.pathはpip(Python Installerと理解)を使用して新しくインストールされたパッケージのパス(stie-package)を検索し、私が新しく作成したパッケージやモジュール(local package,local modules)もpathを登録することで設定します.
偽書を検閲するシステム.pathのコードを見ると、1番インデックスは任意に登録されたpathであることがわかります.
モジュールまたはパケットが上記順序
2.Absolute pathとRelative pathの違い
独自に開発したパッケージをインポートする場合は、パッケージの場所に基づいてインポートパスを正しく宣言し、パッケージのパスをインポートするには絶対パスと相対パスが必要です.絶対パスは絶対パスです.my appというプロジェクトがあると仮定します.
上記のパスの最後のパスを使用すると、次のパスとして表示されます.
すなわちmy appプロジェクトでは,どのファイル,どの場所からインポートしてもパスは常に上と同じであるため,絶対パスと呼ぶ.
絶対パスの欠点は、パスが長くなる可能性があることです.これらの欠点を補うために、相対パスを使用することができる.
相対パスは、絶対パスとは異なるimport位置に基づいてパスを定義します.したがって、相対パスは、通常、ローカルパケットから他のローカルパケットをインポートするために使用されます.
package 2のmodule 3で、package 2のclass 1とpackage 2のサブpackage 1のmodule 5の関数2をインポートする場合は、次の操作を行います.
また、dotは2つ使用できます.2つのポイントは、現在の場所から親ディレクトリへの可能なパスです.
これらはすべて、同じプロジェクト内にパッケージがあると仮定した場合に行われます.別のプロジェクトのパスから別の方法が必要です.syspathで指定:)それでいいです.
3.mainモジュールパッケージのインポート方法
main.pyが独自に設計したローカルパッケージを適用しようとimportを行い、以下のエラーが発生しました.
参考までにadd and multiplyはmainです.pyの親ディレクトリに格納されます.
では、どうすればいいのでしょうか.これも簡単です.絶対パスに変更すると、importは同じプロジェクト(ディレクトリ)に存在するため実行できます.
絶対パスを使いたくなければ、相対パスも完全に可能だと思います.すぐに実行するmain.pyをインポートするプロジェクトの最上位レベルに移動すると、サブパスを参照して実行できますが、:)絶対パスを書きましょう.
4. init.pyファイルの役割
Initの目的は何ですか?このディレクトリがパッケージの一部であることをユーザに伝える役割を果たし,公開範囲を設定する役割も果たす.通常、initファイルは次のタスクを完了するのに役立ちます.導入時に減少する経路の全長 .パッケージにインポート可能な変数/関数/クラス制限は です.他のパケットのインポート時に最初に実行する必要があるコード Initは、パッケージを実行するときに自動的に実行されるモジュールです.関数のinit関数と同じです.では、自動運転のモジュールにロードするモジュールを先に実行すれば、importタイピングを減らすことができます.簡単に言えば、次のコードのようです.
許可する変数、クラス、関数などは、initでそのモジュール(またはモジュール内の関数)などをImport後のallに予め指定しておくことができます.を選択します.pyは記入せず、名前しか記入できません.
また、TILシリーズでは、モジュールやパッケージ、クラス、関数であまり理解されていない内容をまとめます.:)
Pythonはimport時にsearch順を以下のように設定します.
import sys
print(sys.modlues)
>>>
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module 'importlib._bootstrap' (frozen)>, '_imp': <module '_imp' (built-in)>, '_thread': <module '_thread' (built-in)>, '_warnings': <module '_warnings' (built-in)>,
'_weakref': <module '_weakref' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>,
'_frozen_importlib_external': <module 'importlib._bootstrap_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'posix': <module 'posix' (built-in)>,
'encodings': <module 'encodings' from .... '/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/rlcompleter.py'>,
'mod1': <module 'mod1' from '/Users/hoho/Google 드라이브/TIL/Documents/Python/mod1.py'>}
build-inモジュールは、Pythonが提供するPython公式ライブラリを意味します.Pythonをインストールすると自動的に保存され、通常はlibフォルダに保存されます.sys.pathは基本的にlistのstring要素を有する.次のコードを見れば理解できます.
import sys
print(sys.path)
>>>
['', '/Users/hoho/Google 드라이브/TIL/Documents/Python',
'/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
'/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload',
'/Users/hoho/Library/Python/3.7/lib/python/site-packages',
'/usr/local/lib/python3.7/site-packages']
sysとは何ですか.System-Pythonが提供する特定のパラメータと機能の略.オペレーティングシステムモジュールに存在し、Python Interpreter(エディタと理解)が提供する変数と関数を直接制御できます.既にインストールされているため、build-inモジュールに属します.私たちはすでに上で違いを見ましたがsys.モジュールはモジュールの集合、sysです.pathには経路の違いがあります.
システム.modulesはdictの形式でsysです.pathにも違いがあり、リスト内のstringの形式があります.
sys.pathはpip(Python Installerと理解)を使用して新しくインストールされたパッケージのパス(stie-package)を検索し、私が新しく作成したパッケージやモジュール(local package,local modules)もpathを登録することで設定します.
偽書を検閲するシステム.pathのコードを見ると、1番インデックスは任意に登録されたpathであることがわかります.
モジュールまたはパケットが上記順序
modules => built-in => path
で見つからない場合、ModuleNotFoundErrorが発生する.2.Absolute pathとRelative pathの違い
独自に開発したパッケージをインポートする場合は、パッケージの場所に基づいてインポートパスを正しく宣言し、パッケージのパスをインポートするには絶対パスと相対パスが必要です.絶対パスは絶対パスです.my appというプロジェクトがあると仮定します.
└── my_app
├── main.py
├── package1
│ ├── module1.py
│ │ └── function1()
│ └── module2.py
└── package2
├── class 1
├── __init__.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
└── function2()
main.pyで絶対パスを使用する方法は、次のコードに示します.from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2
my appというプロジェクトの最上位レベルのpackage 1,2から始まることがわかります.上記のパスの最後のパスを使用すると、次のパスとして表示されます.
my_app => package2 => subpackage1 => module5.py # 경로
my_app/package2/subpackage1/module5.py # 리눅스의 directory 경로 형식
my_app\package2\subpackage1\module5.py # 윈도우의 형식
my_app.package2.subpackage1.module5.py # 파이썬에서는 slash나 back slash 대신 dot(.)을 사용해서 표현
from package2.subpackage1.module5 import function2 # 위 dot으로 표현한 것을 파이썬에서 임폴트 할 때 쓰는 방법
既にmy appという項目に入っているので、my appは省略します.項目を外したからといって可能だと思わないでください.すなわちmy appプロジェクトでは,どのファイル,どの場所からインポートしてもパスは常に上と同じであるため,絶対パスと呼ぶ.
絶対パスの欠点は、パスが長くなる可能性があることです.これらの欠点を補うために、相対パスを使用することができる.
相対パスは、絶対パスとは異なるimport位置に基づいてパスを定義します.したがって、相対パスは、通常、ローカルパケットから他のローカルパケットをインポートするために使用されます.
package 2のmodule 3で、package 2のclass 1とpackage 2のサブpackage 1のmodule 5の関数2をインポートする場合は、次の操作を行います.
# package2/module3.py
from . import class1 # class1은 package2 에 있다.
from .subpackage1.module5 import function2
dot(.)import宣言ファイルの現在位置を指します.現在の位置はpackage 2/module 3です.したがって、必要なモジュールのパスを現在の位置から宣言するだけでよい.また、dotは2つ使用できます.2つのポイントは、現在の場所から親ディレクトリへの可能なパスです.
# subpackage1/module5.py
from ..module4 import class4
相対パスの利点は、宣言するパスの長さを減らすことですが、混同しやすく、ファイルの場所が変更された場合、パスの場所も変更する必要があります.そのため、できるだけ絶対パスを使うことをお勧めします.これらはすべて、同じプロジェクト内にパッケージがあると仮定した場合に行われます.別のプロジェクトのパスから別の方法が必要です.syspathで指定:)それでいいです.
3.mainモジュールパッケージのインポート方法
main.pyが独自に設計したローカルパッケージを適用しようとimportを行い、以下のエラーが発生しました.
参考までにadd and multiplyはmainです.pyの親ディレクトリに格納されます.
from .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
つまり、相対パスを使用すると、親パッケージがわかりません.どうしてこんなことが起こったのですか.簡単です.相対パスは、現在モジュールをロードするファイルの場所から始まります.つまりname=mainというファイルから始まります.親パッケージ(およびファイル)とサブパッケージ(およびファイル)を検索する場合、相対パスはmainです.pyから始まります.しかしmainとadd and multiplyモジュールは親と子供の関係ではなく、非常にレベルの高い関係です.つまり、Pythonが見つからないため、上記のエラーが発生します.では、どうすればいいのでしょうか.これも簡単です.絶対パスに変更すると、importは同じプロジェクト(ディレクトリ)に存在するため実行できます.
from calculator.add_and_multiply import add_and_multiply
#from .add_and_multiply import add_and_multiply
if __name__ == "__main__":
print(add_and_multiply(1,2))
>>>
/opt/homebrew/bin/python3 /Users/Barney/Desktop/repl/repl57.py
/Users/Barney/Desktop/repl/repl57.py:1: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
5
上記のパスを出力し、結果値の出力を支援します.絶対パスを使いたくなければ、相対パスも完全に可能だと思います.すぐに実行するmain.pyをインポートするプロジェクトの最上位レベルに移動すると、サブパスを参照して実行できますが、:)絶対パスを書きましょう.
4. init.pyファイルの役割
Initの目的は何ですか?このディレクトリがパッケージの一部であることをユーザに伝える役割を果たし,公開範囲を設定する役割も果たす.通常、initファイルは次のタスクを完了するのに役立ちます.
#main.py
from test.test1 import func2
->
#__init__.py
from test.test1 import func2
#main.py
func2()
__init__.pyファイルに次のコードを設定すると、公開するモジュール、クラス、関数、変数などしか公開できません.すなわち,外部でimportを行う場合,利用可能なモジュールが設定される.__all__ = ["vietnam", "thailand"]
含まれているモジュールはすべて公開できます.許可する変数、クラス、関数などは、initでそのモジュール(またはモジュール内の関数)などをImport後のallに予め指定しておくことができます.を選択します.pyは記入せず、名前しか記入できません.
また、TILシリーズでは、モジュールやパッケージ、クラス、関数であまり理解されていない内容をまとめます.:)
Reference
この問題について(Python-パッケージ、モジュールパス), 我々は、より多くの情報をここで見つけました https://velog.io/@holyja/파이썬-패키지-모듈의-경로テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol