[TIL] Modules & Packages
Modules
Module
モジュールは既製でもいいし、自分で作ってもいいです.
## my_module.py
my_module_var = 7
def my_module_func():
return "Hello!"
class MyModuleClass:
pass
👆🏻 一般的なファイルを作成し、コードを保存した後このモジュールを別のファイルからインポートすると使用できます.
<모듈 이름>.<모듈에서 사용하길 원하는 변수/함수/클래스 이름>
import my_module
どのファイル、どのクラスの関数または変数を書き込むか分かりません.モジュールの前に名前を付ける必要があります(namespace structure!)
👇🏻 モジュールの構造と作業順序!
モジュールのインポート方法!
1.importキーのみ使用
2. import from
from <모듈 이름> import <함수/변수/클래스1>, <함수/변수/클래스2>, ..., <함수/변수/클래스N>
-
from my_module import my_module_func, my_module_var
print(my_module_var)
my_module_func()
:モジュールで明示的に使用する場合に使用します.(ただしlocalscopeを持つ変数と名前の競合は推奨されません)
3. import as
from my_module import my_func as f1
from my_module2 import my_func as f2
from my_module3 import function_with_name_too_long as f3
-
f1()
f2()
f3()
:インポートモジュールの要素を必要な名前として使用します.import my_module as m1
-
m1.my_module_func()
:モジュール名を指定することもできます.Packages
(より大きく複雑なコードではなく)
他の場所からモジュールにロードして使用します!
👆🏻 Pythonファイルからなるディレクトリがパッケージになります
(ディレクトリ名=>package名)
import pkg.mod1
from pkg.mod2 import func2
pkg.mod1.func2()
func2()
__init__.py
パッケージを使用する場合は、ファイルを使用して初期設定# __init__.py
from .mod1 import func2
# main.py
from pkg import func2
func2()
👆🏻 これにより、関数名を直接呼び出すことができます.__all__
:packageでインポートできるすべての要素を定義:この変数を使用すると、パッケージの外部インポート時に使用されないようにします.
:default値は、すべての関数/変数/クラスです.
個別に定義すると、これらの要素をインポートできないように制限します!
# __init__.py
from .mod1 import func2
from .mod2 import func3
__all__ = ['func2', 'func3']
# main.py
from pkg import *
func2()
func3()
func4() ## <== Error. func4 함수는 __all__ 에 정의되지 않았으므로 import 될 수 없음.
👆🏻 String値の要素リスト.インポートする要素をstringでlistに宣言すればいいです.
How Import Statement Finds Modules & Packages
では、Pythonはどのようにモジュールとパッケージをインポートしますか?
どうやって検索しますか?import abc
👆🏻 yorokeimport、しかしPythonはどのようにモジュール/packageを探しますかを知りません
どんな原理で探しますか?
1) 3steps to find module/package
import abc
sys.modules
Pythonが最初に確認した場所!
built-in modules
見つけやすい
sys.path
['',
'/Users/song-eun-u/anaconda3/bin',
'/Users/song-eun-u/anaconda3/lib/python36.zip',
'/Users/song-eun-u/anaconda3/lib/python3.6']
👉🏻 Pythonはリストのパスを1つずつチェックし、そのパスにインポートする要素があるかどうかを決定します.sysモジュールsysをインポートします.modules, sys.pathを出力、変更できます.(👇🏻 Yoroche!)
import sys
-
print(sys.path)
print(sys.modules)
Pythonは、この3つのステップでインポートするモジュールとパッケージを決定します.見つからない場合はModuleNotFoundErrorに戻ります
2) Absolute path & Relative path
内蔵モジュールとpipでインストールされたすべての外部ビューモジュール
最初の3段階で見つけることができますが.
自社開発のlocal packageをインポートする場合は、場所に応じてパスを正しく宣言します.
└── my_app
├── main.py
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── __init__.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
👆🏻 プロジェクト構造を次のように仮定します.Absolute path:絶対パス
from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2
リレーショナルパスリレーショナルパス:相対パスそうたいぱす
# package2/module3.py
-
from . import class1
from .subpackage1.module5 import function2
-
# subpackage1/module5.py
from ..module4 import class4
dot .. 両方のパスは、現在の場所から親ディレクトリへのパス
欠点は、ファイルの場所が変更された場合、パスの場所を変更する必要があることです.
3)練習-計算パッケージの作成
プロジェクトの作成
👇🏻 main.py
# absoulte path
#from calculator.add_and_multiply import add_and_multiply
-
# relative path
from .calculator.add_and_multiply import add_and_multiply
-
if __name__ == '__main__':
print(add_and_multiply(1,2))
👇🏻 add_and_multiply.pyfrom .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
👇🏻 multiplication.pydef multiply(a,b):
return(a*b)
Python公式ドキュメント
ある人は“no par母package”と言います
相対経路なので、このような問題が発生します...
公式文書を参考に調べてみました.pyファイルには独自のルールがありますか?
👆🏻 mainモジュールの名前はいつも
__main__.py
と言って、それにファイル名を変えて、少しも影響していませんて、ファイル名は変えて、同じ間違いが現れましたいずれにしても、相対経路自体が問題だと思いますが...
👆🏻 もとは正式な書類の最後の部分で、mainmoduleは親切に私に教えてくれて、必ず絶対パスを使います.もしもし、あなたも知らないハラン.
main.pyファイルからパケットの前の相対パスタグが削除されました.
今からちゃんと帰れ!
👆🏻 まず相対パスでインポートすると、エラーが発生します.
👆🏻 No nown parent packageはパッケージ名を指定しますが、importは含まれません.
👆🏻 絶対パスでパッケージ名を指定してもエラー!モジュールがありません!!
どうしたんですか.
👆🏻 絶対パスは現在のディレクトリから始まりますが、必ずしも最上位ディレクトリから始まるわけではありません.
スクリプトが属するパスからdefaultとして指定された現在のディレクトリを決定できます.
私の場合、絶対パスの起点はcalculator packageディレクトリなので、それ以外の絶対パスに指定すると正常に動作します!
Reference
この問題について([TIL] Modules & Packages), 我々は、より多くの情報をここで見つけました https://velog.io/@haileeyu21/TIL-Modulesテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol