Python プロジェクトのパッケージ化とデプロイメント (1): モジュールとパッケージの概念と関係

現在、さまざまな Python チュートリアルに Python のパッケージ化およびデプロイメント技術が含まれていることはほとんどないか、説明があまりにも表面的で一方的です。私は原則から始めて、それを例と組み合わせ、標準的な操作手順についての提案を提供して、Python プログラミング愛好家向けに Python プロジェクトのパッケージ化とデプロイメントに関するより詳細なリファレンス チュートリアルを提供するように努めています。

このチュートリアルの他の章

Python は動的に型指定されるプログラミング言語ですが、事前にコンパイルする必要はありません。ただし、Python プロジェクトは、.py ファイル、データ ファイル、リソース ファイルなどのセットでも構成されます。ほとんどのプロジェクトはサードパーティのライブラリも参照し、依存関係の管理もあります。したがって、Python のプロジェクト管理は Java や C++ などの他の言語と似ています。Python プロジェクトを構築するときに直面する基本概念は、モジュールとパッケージです。

1. モジュールとパッケージの概念

Python のモジュールは、変数定義、関数定義、クラス定義、その他の実行可能ステートメントを含む個別の .py ファイルです。モジュールは、インタプリタを使用して直接実行したり、他のモジュールにインポートしたりできる独立したコード単位です。

一方、パッケージは、ディレクトリに含まれるモジュールのコレクションです。パッケージを使用すると、複数の関連モジュールを共通の名前空間にグループ化できるため、コード ベースの整理と構造化が容易になります。

コードをモジュールとパッケージに分割すると、次のような大きなメリットが得られます。

  • 保守性。コードをモジュールに分割すると、モジュールはアプリケーションの 1 つの部分のみを処理するように設計されているため、アプリケーション全体に影響を与えることなく、アプリケーション全体の独立した部分に変更を加えることができます。
  • 再利用性。これはソフトウェア開発の重要な部分であり、コードを一度記述するだけで、アプリケーションのさまざまな部分で必要に応じて何度でも使用できます。これにより、クリーンで簡潔なコードを書くことができます。
  • 役割分担と協力を促進します。モジュール式コードを使用すると、チーム内のさまざまな開発者が、互いに干渉することなく、同じアプリケーションのさまざまな部分 (モジュール) を担当できます。
  • 読みやすさ。コードをモジュールとパッケージに分割すると、コードの可読性が向上します。ファイル内のさまざまなコードの機能を簡単に判断できます。たとえば、databaseConnection.py というファイルがあるとします。名前からだけで、このファイルがデータベース接続を処理することがわかります。

2. モジュールの詳細説明

モジュールには、実行可能なステートメントと関数定義が含まれています。これらのステートメントはモジュールを初期化するために使用され、インポート ステートメントが最初にモジュール名を検出したときにのみ実行されます。(これらのステートメントは、ファイルがスクリプトとして実行されるときにも実行されます。)

各モジュールには独自のプライベート名前空間があり、モジュール内で定義されているすべての関数のグローバル名前空間として使用されます。したがって、モジュール作成者は、ユーザー グローバル変数との偶発的な競合を心配することなく、モジュール内でグローバル変数を使用できます。一方、何をすべきかわかっている場合は、モジュール関数を参照するのに使用されるのと同じ表記法を使用して、modname.itemname 経由でモジュールのグローバル変数にアクセスできます。

2.1 モジュールの作成例

IDE またはテキスト エディタを開いてファイルを作成し、sample.py という名前を付けて、次のコードを入力します。

# sample.py

# create a variable in the module
sample_variable  = "This is a string variable in the sample.py module"

# A function in the module
def say_hello(name):
  return f"Hello, {
      
      name}  welcome to this simple module."

# This is another function in the module
def add(a, b):
  return f"{
      
      a} + {
      
      b} is = {
      
      a+b}"

print(sample_variable)
print(say_hello("小明"))
print(add(2, 3))

上記のコードは、sample.py というモジュールを定義します。これには、sample_variable という変数が含まれており、その値は「これは、sample.py モジュールの文字列変数です」という文字列です。このモジュールには 2 つの関数定義も含まれています。呼び出されると、say_hello() 関数は name パラメータを受け取り、それに名前を渡すと、ウェルカム メッセージが返されます。add() 関数は、渡された 2 つの数値の合計を返します。
モジュールはプログラムまたはアプリケーションの他の部分で使用されますが、独立して実行できます。このモジュールを実行するには、開発環境に Python をインストールする必要があります。次のコマンドを使用して、ターミナル上で実行できます。

python sample.py 

または

python3 sameple.py

演算結果

This is a string variable in the sample.py module
Hello, 小明  welcome to this simple module.
2 + 3 is = 5

独立したモジュールとして実行することもできますが、ほとんどの使用シナリオでは、モジュールは通常、他のモジュールまたは Python メイン プログラムをインポートすることによって使用されます。したがって、あるモジュールの変数、関数、クラスを別のモジュールで使用するには、そのモジュールをインポートする必要があります。モジュールをインポートするにはさまざまな方法があるため、モジュールをインポートする方法を見てみましょう

2.2 インポート文

別のモジュールの内容をこのモジュールにインポートするには、import module_name を使用します。たとえば、another_module.py のインポート サンプルを使用します。

# another_module.py

import sample

print(sample.sample_variable)
print(sample.say_hello(“John”))
print(sample.add(2, 3))

上記のコードは、sample.py モジュールから関数をインポートして、another_module.py で使用できるようにする方法を示しています。モジュールをインポートする場合、.py 拡張子を含める必要はないことに注意してください。

2.3 from … import … ステートメントを使用する

from キーワードを使用して、特定の関数または変数をインポートすることもできます。モジュール内に多数の関数と変数が定義されており、それらすべてを使用したくないとします。from キーワードを使用して、使用する関数または変数を指定できます。


# another_module.py

from sample import add

print(add(10, 4))

上記のコードは、サンプル モジュールから add() 関数を具体的にインポートしたことを示しています。
from キーワードを使用するもう 1 つの利点は、インポートされた関数を使用するときに、関数に名前を付けたり、親モジュールの名前を先頭に追加したりする必要がないことです。これにより、コードがよりクリーンで読みやすくなります。

2.4 as キーワードを使用する

「as」を使用して、モジュールの別名または代替名を指定できます。

場合によっては、非常に長い、または判読できないモジュール名を定義することがあります。Python は、モジュールのインポートにエイリアスを提供する方法を提供します。これには、 as キーワードを使用します。

# another_module.py

import sample as sp

result = sp.add(5, 5)
print(result)
print(sp.say_hello("Jason"))

このコードは、サンプル モジュールのインポートを示しています。モジュールにはエイリアスが与えられていますspsp の使用は、sample の呼び出しとまったく同じです。変数や関数にもアクセスできます。

上記の 3 つの方法を使用すると、あるモジュールの変数や関数を別のモジュールで使用できるため、コードを 1 つのファイルに入れる必要がなくなり、アプリケーションの可読性が向上します。

モジュール名に名前を付ける場合は、小文字を使用し、_2 つの単語の間に次の行を使用するのが最善です。たとえば、データベース接続を処理するモジュールがあり、database_connection.py という名前を付けることができます。また、Python の名前では大文字と小文字が区別されるので、インポートするときは必ず正しいモジュール名を使用してください。

全体として、モジュールを使用すると、読みやすく保守しやすい方法でコードを作成および整理できます。

2.5 コード内のモジュール名を取得する

モジュール内では、グローバル変数 name を介してモジュール名 (つまり、文字列) を取得できます前の例を少し変更して、サンプルと another_module.py 内のモジュール名を取得します。

# another_module.py

import sample

print(sample.sample_variable)
print(sample.say_hello(“John”))
print(sample.add(2, 3))
print(__name__)

another_module.py で、sample.py モジュール名を取得します。

# another_module.py

import sample as sp

result = sp.add(5, 5)
print(result)
print(sp.say_hello("Jason"))
print(sp.__name__) 

3. パッケージの詳しい説明

Python のパッケージは、関連するモジュールをディレクトリに整理する方法です。パッケージは通常、同じ機能を実行するモジュール、または同じコンポーネントに属するモジュールをグループ化するために使用されます。
パッケージは、同じパッケージ、モジュール、関数 (グローバル変数) の階層関係を「.」ピリオドを使用して表します。たとえば、モジュール名 AB は、A という名前のパッケージ内の B という名前のサブモジュールを指定します。

1) パッケージ、モジュール、ファイルの関係

Package(パッケージ)、Module(モジュール)、file(ファイル) 3つの関係は、

  • パッケージはモジュールで構成されており、モジュールの名前空間に相当します。
  • モジュール、関数コードを含む .py コード ファイルもモジュールと呼ばれますが、config.py , __init__.pyモジュールと呼ぶことはできません。
    ここに画像の説明を挿入します

2) パッケージとディレクトリの関係

形式的には、パッケージはディレクトリとして理解できますが、コードを含むすべてのディレクトリがパッケージであるわけではありません。
ここに画像の説明を挿入します

両者を区別する鍵は、パッケージ ディレクトリには__init__.pyファイルが含まれており、このファイルが含まれていないものはパッケージ ディレクトリとは呼べないということです。

パッケージにはサブパッケージを含めることができますが、サブパッケージもそのディレクトリ内に存在する必要があります。__init__.py

使用する場合は、ドットを使用して階層関係を示します

mypkg.mymodule.func_1()

3) パッケージ、モジュール、関数をインポートする

現在のプロジェクトはサウンドファイルとサウンドデータを統合的に処理するプロジェクトであるとする。サウンド ファイルにはさまざまな形式 (.wav、.aiff、.au などの拡張子で識別されることがよくあります) があるため、異なるファイル形式間の変換のために、ますます多くのモジュールのコレクションを作成し、維持する必要があります。サウンド データのさまざまな処理 (サウンドのミキシング、エコーの追加、イコライザー機能、人工的なステレオ効果の作成など) を実装するには、無限のモジュール ストリームをプログラムする必要があります。次の階層ファイル ツリーは、このパッケージのアーキテクチャを示しています。

sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

前のセクションで説明したように、__init__.pyディレクトリにはパッケージが含まれています。したがって、上記のプロジェクトでは、sound がプロジェクトのメイン ディレクトリであり、パッケージでもあり、その下にフィルター、エフェクト、フォーマットの 3 つのサブパッケージがあります。各サブパッケージの下にはいくつかのモジュールがあります。

サブパッケージをインポートする方法。
絶対的な引用:

sound.filters.vocoder モジュールは、sound.Effects サブパッケージの下にある echo モジュールを使用する必要があります。次のように引用されます。

from sound.effects import echo

相対参照

from . import echo は、現在のパッケージの下にある echo モジュールをインポートすることを意味します

from ... import format は、親ディレクトリから format サブパッケージをインポートすることを意味します。

4) サードパーティパッケージをインポートする

Python コミュニティによって検証されたパッケージのサードパーティ パッケージは、通常、ライブラリとも呼ばれます。インポート方法は次のように分かれています。ソースによると、次のようになります。

(1) pip によってインストールされたパッケージをインポートします
。PyPi メソッドに従って、つまり pip によってインストールされたサードパーティ パッケージをインポートします。インポート時に、Python インタープリターは Python インストール ディレクトリの Lib/site-packages/ の下を検索します。見つからない場合は、エラーが報告されます。

import numpy
import pandas 

(2) サードパーティ パッケージを手動でインポートする
サードパーティ パッケージの絶対パスを sys.path 変数に追加する必要があります。たとえば、サードパーティ パッケージ pkg_a のパスは /usr/local/pkg_a です。インポートおよび使用例は次のとおりです。


import sys
 
# appending a path
sys.path.append('/usr/local/pkg_a')
 
# importing required module
import pkg_a
from pkg_a import module_a
 
# accessing its content
module_a.foo()

4. モジュール検索パス

よくある質問: test/テスト ファイルにパッケージとモジュールをインポートするときに、テスト ディレクトリがプロジェクトのサブパッケージではないため、インポート エラーの問題がよく発生します。デフォルトのインポート方法によると、モジュール パスはインポートできません。見つけられた。

.py モジュール ファイルでは、スパムなどの他のモジュールをインポートするときに、インタープリターは最初に Python 組み込みモジュールを検索します。これらのモジュール名は sys.builtin_module_names にリストされています。見つからない場合は、変数 sys.path で指定されたディレクトリのリストで spam.py という名前のファイルを検索します。
sys.path は次から初期化されます。

  • .py スクリプトがコマンド ラインから直接実行されるディレクトリ (ファイルが指定されていない場合は現在のディレクトリ)。
  • PYTHONPATH (内容はディレクトリのリストです)。
  • Python インストール ディレクトリの下の Lib/site-packages サブディレクトリ。
>>> import sys
>>> sys.path
['',
'C:\\opt\\Python36\\python36.zip',
'C:\\opt\\Python36\\DLLs',
'C:\\opt\\Python36\\lib',
'C:\\opt\\Python36',
'C:\\Users\\NanoDano\\AppData\\Roaming\\Python\\Python36\\site-packages',
'C:\\opt\\Python36\\lib\\site-packages',
'C:\\opt\\Python36\\lib\\site-packages\\win32',
'C:\\opt\\Python36\\lib\\site-packages\\win32\\lib',
'C:\\opt\\Python36\\lib\\site-packages\\Pythonwin']

sys.path を変更する 3 つの方法:

(1) パスを追加する

sys.path.append(``'C:/Users/Vanshi/Desktop'``)

(2) sys.path は、初期化時に Python システム変数 PYTHONPATH を読み取ります。PYTHONPATH は起動スクリプトで変更できます。構文は環境変数のパスと同じです

set PYTHONPATH=C:\pypath1\;C:\pypath2\
python -c "import sys; print(sys.path)"
# Example output
['', 'C:\\pypath1', 'C:\\pypath2', 'C:\\opt\\Python36\\python36.zip', 'C:\\opt\\Python36\\DLL

set 変数名 = 値は一時的に追加されるため、ターミナルを閉じると無効になります。

変更可能な環境変数を永続的に追加するには、
setx ENV_NAME env_value を注意して使用する必要があります。

のように:

setx -m PATH “%PATH%;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin”

Linuxで環境変数コマンドを追加する

import PYTHONPATH='/some/extra/path'

(3) サイトモジュールを使用してsys.pathを変更する

プログラム コード内の sys.path 変数を変更して、システムの起動時にこの変数がロードされ、対応するモジュールが見つかるようにします。

import site
import sys

site.addsitedir('/the/path')  # Always appends to end
print(sys.path)

おすすめ

転載: blog.csdn.net/captain5339/article/details/132637042