1つのファイルにいくつのクラスを入れる必要がありますか?[閉まっている]


274

私は、ファイルごとに1つのパブリッククラスを持つことができるJavaモデルに慣れています。Pythonにはこの制限がありません。クラスを編成するためのベストプラクティスは何でしょうか。


8
他の言語の要件と規則を考えると、これは合理的な質問だと思います。答えは「<Pythonモジュールとパッケージを定義する>」であり、それ以上は好みの問題(/ opinion)です- その答え自体は意見ではありません
david.libremone 2016年

回答:


333

Pythonファイルは「モジュール」と呼ばれ、「意味のある」ソフトウェアを構成する1つの方法です。もう1つは「パッケージ」と呼ばれるディレクトリです。

モジュールは、1つまたは2ダースの密接に関連するクラスを持つことができる別個のものです。秘訣は、モジュールはインポートするものであり、ソフトウェアを読んだり、保守したり、拡張したりする人々が完全に理解できるようにインポートする必要があるということです。

ルールは次のとおりです。モジュールは再利用の単位です

単一のクラスを簡単に再利用することはできません。何の問題もなくモジュールを再利用できるはずです。ライブラリのすべて(およびダウンロードして追加するすべて)は、モジュールまたはモジュールのパッケージです。

たとえば、スプレッドシートを読み取り、いくつかの計算を行い、結果をデータベースにロードする作業をしているとします。メインプログラムをどのように見せたいですか?

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ステートメントで描写している全体的な組織です。


24
はは、引用の「センス」が好きです。
2009

27
@cdleary:ある人の感覚は別の人の狂気です。通常、賢明なモジュールを定義できます。ただし、大きなアプリケーションでは、常に分析の複数の側面があり、ある人が別の人の機能のスライスとダイシングで髪を分割します。
S.Lott、2009

4
上記の勧告はと一致しているdocs.python-guide.org/en/latest/writing/structure
Mayank Jaiswal

4
実際に質問に答えない答え、読みやすさについてはどうですか?500行を超えるファイルを読むのは難しいです。
Vedmant 2018

38

人為的な制限はないので、理解できる内容に依存します。論理的にグループ化された、かなり短く単純なクラスがたくさんある場合は、それらをまとめて投げます。大きく複雑なクラスや、グループとして意味をなさないクラスがある場合は、クラスごとに1つのファイルに移動します。またはその間に何かを選びます。状況の変化に応じてリファクタリングします。


23

次の理由でJavaモデルが好きです。各クラスを個別のファイルに配置すると、ソースコードを参照するときにクラスが見やすくなり、再利用が促進されます。多数のクラスが1つのファイルにグループ化されている場合、他の開発者には、プロジェクトのディレクトリ構造を参照するだけで再利用できるクラスがあることがわかりにくい場合があります。したがって、クラスを再利用できると思われる場合は、独自のファイルに入れます。


2
完全にあなたと同意します。1つのファイルに複数のパブリッククラスを含めると直感的に理解できず、誰かが構造を非表示にしたくて、くどくどくした感じがするように、コードを理解しにくくします。特に、JavaからPythonに移行する場合はなおさらです。
WebComer 2018

特に、JavaからPythonに移行する場合はなおさらです。彼らは以前、Pythonでは1つのファイルに多くのクラスをスローしていました)
WebComer

14

それは、プロジェクトの大きさ、クラスの長さ、他のファイルから使用されるかどうかなどに完全に依存します。

たとえば、データの抽出に一連のクラスを使用することがよくあります。そのため、4行または5行のクラスで、長さが1行しかない場合があります(class SomeData: pass)。

これらのそれぞれを別々のファイルに分割するのは愚かです-しかし、それらは異なるファイルから使用される可能性があるため、これらすべてを別々のファイルに入れるdata_model.pyことは理にかなっているので、from mypackage.data_model import SomeData, SomeSubData

たくさんのコードが含まれているクラスがある場合、おそらくそれだけが使用するいくつかの関数がある場合、このクラスとヘルパー関数を別のファイルに分割することをお勧めします。

そうfrom mypackage.database.schema import MyModelではないように構造化するfrom mypackage.email.errors import MyDatabaseModel必要があります。インポートする場所に意味があり、ファイルが数万行に満たない場合は、正しく構成されています。

Pythonモジュールのドキュメントは、パッケージを整理する上でいくつかの有用な情報を持っています。


1
Pythonモジュールのドキュメントへのリンクが壊れています。多分セクション6.4 Modules.Packagesは今意図されたリンクですか?
cod3monk3y 2014

9

ファイルの大きさに悩まされて、関連性の望ましい構造が自然に現れ始めたとき、私は自分が物事を分割していることに気づきます。多くの場合、これらの2つの段階は一致しているように見えます。

完全に異なる構造の順序が必要であることに気づき始めるので、物事をあまりにも早く分割すると、それは非常に煩わしいかもしれません。

一方、.javaファイルまたは.pyファイルが約700行を超えると、「その特定のビット」がどこにあるのかを常に覚えようとすることに苛立ち始めます。

Python / Jythonでは、インポートステートメントの循環依存も役割を果たしているようです。協調する基本的なビルディングブロックをあまりにも多くのファイルに分割しようとすると、言語のこの「制限」/「不完全性」によって、グループ化が強制されるようです。むしろ賢明な方法で。

パッケージに分割することについては、よくわかりませんが、モジュール化のすべてのレベルで、厄介なルールと幸せな構造の出現という同じルールが機能すると思います。


6

大きくて複雑にせずに、論理的にグループ化できる限り多くのクラスをそのファイルに入れるといいでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.