同じファイルに複数のクラスが定義されているとPythonicと見なされますか?


31

初めてPythonを使用して、同じファイルに複数のクラスを記述することになりました。これは、クラスごとに1つのファイルを使用するJavaなどの他の言語とは対照的です。

通常、これらのクラスは1つの抽象基本クラスで構成され、1-2の具体的な実装が使用されますが、使用方法はわずかに異なります。以下にそのようなファイルを1つ投稿しました。

class Logger(object):

    def __init__(self, path, fileName):
        self.logFile = open(path + '/' + filename, 'w+')
        self.logFile.seek(0, 2)

    def log(self, stringtoLog):
        self.logFile.write(stringToLog)

    def __del__(self):
        self.logFile.close()

class TestLogger(Logger):   

    def __init__(self, serialNumber):
        Logger.__init__('/tests/ModuleName', serialNumber):

    def readStatusLine(self):
        self.logFile.seek(0,0)
        statusLine = self.logFile.readLine()
        self.logFile.seek(0,2)
        return StatusLine

    def modifyStatusLine(self, newStatusLine):
        self.logFile.seek(0,0)
        self.logFile.write(newStatusLine)
        self.logFile.seek(0,2)

class GenericLogger(Logger):

    def __init__(self, fileName):
        Logger.__init__('/tests/GPIO', fileName):

    def logGPIOError(self, errorCode):
        self.logFile.write(str(errorCode))

上記のように、Loggerの基本クラスがあり、その下に実装の違いがいくつかあります。

質問: これはPythonの標準ですか、それともどの言語の標準ですか?この実装を使用すると、どのような問題が発生する可能性がありますか?

編集:私は本当にこの特定のファイルに関するガイダンスを探しているのではなく、より一般的な意味で探しています。クラスが3〜5の中程度に複雑なメソッドになった場合はどうなりますか?それらを分割するのは理にかなっていますか?ファイルを分割する必要があると言った場合のカットオフはどこですか?


3
ファイルごとに1つのクラスに制限することは、C ++のことではありません。Javaは、回避すべきものとみなされる場所について私が知っている唯一の言語です。C ++では、1つの.h / .cppファイルに1つのプライマリクラスと多数のヘルパークラスが存在することは非常に一般的です。
ロボット

@StevenBurnap正しいので、例としてc ++を削除しました。
アンプト

1
また、自動読み込みを容易にするためにphpでも実行されます。一方、phpでは、名前空間を明示的に宣言できます。
ボードー

回答:


24

大丈夫だよ。参照用に、C ++でも問題ありません。

密結合されたものをまとめることは賢明な習慣です。不適切な結合を回避することもお勧めします。適切なバランスをとることは厳密なルールの問題ではありませんが、さまざまな懸念のバランスをとることです。

経験則:

  1. サイズ

    大きすぎるファイルは見苦しいかもしれませんが、ここではほとんどそうではありません。Uさはおそらくファイルを分割する十分な理由ですが、その美的感覚を開発することは主に経験の問題であるため、先験的に何をすべきかを理解するのに役立ちません

  2. 関心事の分離

    具象実装の内部懸念が非常に異なる場合、単一のファイルにすべての懸念が蓄積されます。たとえば、依存関係が重複しない実装では、単一のファイルがそれらすべての依存関係の和集合に依存します。

    そのため、サブクラスの依存関係への結合は、インターフェイスへの結合よりも重要であると考えるのが合理的である場合があります(または、逆に、インターフェイス実装する懸念は、その実装の内部の懸念よりも弱い)。

    具体的な例として、汎用データベースインターフェイスを取り上げます。インメモリDB、SQL RDBMS、およびWebクエリをそれぞれ使用する具体的な実装には、インターフェイス以外に共通点がない場合があり、軽量のインメモリバージョンを必要とするすべての人にSQLライブラリのインポートも強制するのは厄介です。

  3. カプセル化

    あなたがができ、同じモジュールでよくカプセル化されたクラスを作成し、それは可能性がありますが、そうでない場合は、モジュールの外にエクスポートされません実装の詳細へのアクセス権を持っているという理由だけで、不要な結合を促します。

    これは私が思う貧しいスタイルですが、習慣を本当に破ることができない場合は、モジュールを分割することでより良い規律を強制することができます。


2
1つのファイルにクラスを結合することの正常性を示す外部参照を引用するか、なぜ問題がないかを示す詳細な説明を提供すれば、答えはより強力になります。

1
質問を編集して、これは単に私が意味するものの例であり、質問の性質を正確に表していないことを指摘しました。必要な場所に単純にインポートするよりも、同じファイルに保存するほうがよいのはなぜですか?
アンプト

多数の小さなファイルを保持することは、いくつかの巨大なファイルを保持するのと同じくらい管理が難しい場合があります。Pythonはかなり簡潔な言語です。あなたの例はこれを示しています。これら3つのクラスは直接関連しており、スクロールせずに単一のエディターウィンドウに収まる可能性があります。
ロボットをゲット

1
@ GlenH7-参照についてはわかりません。直接主張をすることから、自分の選択バイアスが有効であると主張することへとシフトしているからです。代わりに説明に集中しようとしました。
役に立たない

7

pythonicとは何かを知るための私の通常の参照文書。

単純なものは複雑なものよりも優れています。

ネストはフラットよりも優れています。

Pythonの禅から

ほとんど例外なく、クラス名はCapWords規則を使用します。

パッケージ名とモジュール名モジュールには、すべて小文字の短い名前を付ける必要があります。[...]モジュール名はファイル名にマッピングされます

PEP 8から

私の解釈では、物事をシンプルかつフラットに保つので問題ないということです。また、クラス名とファイル名は大文字と小文字が異なるため、とにかく同一であるとは想定されていないため、複数の関連クラスをファイルにパックしても問題は発生しません。


7
これを質問に関連する部分に減らしてもらえますか?私はこれらの両方を何度も読みましたが、特に現在の質問に関連する部分を選ぶのに苦労しています
アンプト

1
実際、回答を編集しました。
-SylvainD

1

あなたが今持っているものは大丈夫です。移動して標準ライブラリを参照します-単一のファイルに複数の関連クラスを持つモジュールがたくさんあります。ある時点で状況は大きくなり、最終的には複数のファイルを含むモジュールの使用を開始することになりますが、実際のタイミングに関するルールはありません。1つのファイルが「大きすぎる」と感じ始めると、事態は単に分裂します。


0

間違いなく大丈夫です。実現される限り、1つのファイルに複数のクラスを含めることをお勧めします。一般に、クラスは短く簡潔に保つ必要があり、巨大なモノリシッククラスを構築するよりも、動作を2つ以上のクラスに分割する必要があります。いくつかの小さなクラスを書くとき、同じファイルに関連するクラスを保持することが本当に必要であり、役立ちます。


-1

要するに-地獄はい。

さらに、単一のファイルに複数のクラスがあると、非常に便利な場合があります。一部のパッケージ(sixbottle)は、pipをインストールせずにサードパーティのモジュールに簡単に統合できるように、単一のファイルで明示的に出荷されます(望ましい場合があります)。ただし、コードを適切に整理してください。読みやすくするために、コードコメントと分離ブロックを集中的に使用します。


3
これはかなりのオーバー何も追加していないようです前の回答数年前に投稿し
ブヨ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.