ファイルごとに1つのパブリッククラスを持つことができるJavaモデルに慣れています。 Pythonにはこの制限はありません。クラスを整理するためのベストプラクティスは何でしょうか。
Pythonファイルは「モジュール」と呼ばれ、「理にかなっている」ようにソフトウェアを整理する1つの方法です。もう1つは、「パッケージ」と呼ばれるディレクトリです。
モジュールは、1つまたは2つのダースの密接に関連するクラスを持つことができる別個のものです。秘Theは、モジュールはインポートするものであり、そのインポートは、ソフトウェアを読んで、保守し、拡張する人々にとって完全に賢明である必要があるということです。
ルールは次のとおりです。モジュールは再利用の単位です。
単一のクラスを簡単に再利用することはできません。モジュールを問題なく再利用できるはずです。ライブラリ内のすべて(およびダウンロードして追加するすべて)は、モジュールまたはモジュールのパッケージです。
たとえば、スプレッドシートを読み取り、いくつかの計算を行い、結果をデータベースにロードするものに取り組んでいます。メインプログラムをどのように見せたいですか?
from ssReader import Reader
from theCalcs import ACalc, AnotherCalc
from theDB import Loader
def main( sourceFileName ):
rdr= Reader( sourceFileName )
c1= ACalc( options )
c2= AnotherCalc( options )
ldr= Loader( parameters )
for myObj in rdr.readAll():
c1.thisOp( myObj )
c2.thatOp( myObj )
ldr.laod( myObj )
インポートは、概念またはチャンクでコードを整理する方法と考えてください。各インポートに含まれるクラスの数は正確には関係ありません。重要なのは、import
ステートメントで描写している組織全体です。
人為的な制限がないので、それは本当に理解できるものに本当に依存します。論理的にグループ化されたかなり短い、単純なクラスがたくさんある場合は、それらをひとまとめにします。大きくて複雑なクラス、またはグループとして意味をなさないクラスがある場合は、クラスごとに1つのファイルを作成します。または、間に何かを選びます。状況の変化に応じてリファクタリングします。
次の理由でJavaモデルが好きです。各クラスを個別のファイルに配置すると、ソースコードを参照するときにクラスが見やすくなるため、再利用が促進されます。多数のクラスが1つのファイルにグループ化されている場合、プロジェクトのディレクトリ構造を参照するだけで再利用できるクラスがあることは、他の開発者には明らかではありません。したがって、クラスが再利用される可能性があると思われる場合は、独自のファイルに入れます。
プロジェクトの大きさ、クラスの長さ、他のファイルから使用するかどうかなどに完全に依存します。
たとえば、データ抽象化のために一連のクラスを使用することが非常に多いため、1行の長さ(class SomeData: pass
)だけの4つまたは5つのクラスが存在する場合があります。
これらを個別のファイルに分割するのは愚かなことですが、異なるファイルから使用される可能性があるため、これらすべてを個別のdata_model.py
ファイルに入れるのが理にかなっているので、from mypackage.data_model import SomeData, SomeSubData
クラスに多くのコードがあり、おそらくそれだけが使用するいくつかの関数がある場合、このクラスとヘルパー関数を別のファイルに分割することをお勧めします。
from mypackage.database.schema import MyModel
ではなくfrom mypackage.email.errors import MyDatabaseModel
を行うように構造化する必要があります-意味のあるものをインポートする場所で、ファイルの長さが数万行ではない場合は、正しく整理されています。
Python Modules documentation には、パッケージの編成に関する有用な情報があります。
ファイルの大きさに悩まされ、関連性の望ましい構造が自然に現れ始めたとき、私は物事を分割しています。多くの場合、これら2つの段階は一致するようです。
構造を早めに分割すると、まったく異なる構造の順序付けが必要であることに気づき始めるため、非常に面倒です。
一方、.Javaファイルまたは.pyファイルが約700行を超えると、「その特定のビット」がどこにあるのか思い出そうと常にイライラし始めます。
Python/Jythonでは、importステートメントの循環依存も役割を果たしているようです。協調する基本的なビルディングブロックをあまりにも多くのファイルに分割しようとすると、言語のこの「制限」/「不完全」により、グループ化が強制されるようです。むしろ賢明な方法で。
パッケージに分割することについては、私は本当に知りませんが、おそらく、同じレベルの煩わしさと幸福な構造の出現は、モジュール性のすべてのレベルで機能します。
そのファイルに論理的にグループ化できる限り多くのクラスを入れて、大きすぎて複雑にしないようにしたいと思います。