Сколько классов следует помещать в один файл?

Я использую модель Java, где у вас может быть один открытый класс для каждого файла. У Python нет этого ограничения, и мне интересно, что лучше всего подходит для организации классов.

Ответ 1

Файл Python называется "модулем", и это один из способов организовать ваше программное обеспечение, чтобы оно "чувствовало". Другой - это каталог, называемый "пакетом".

Модуль - это отличная вещь, которая может иметь один или два дюжины тесно связанных классов. Фокус в том, что модуль - это то, что вы будете импортировать, и вам нужен этот импорт, чтобы он был совершенно разумным для людей, которые будут читать, поддерживать и расширять ваше программное обеспечение.

Правило таково: модуль является единицей повторного использования.

Вы не можете легко повторно использовать один класс. Вы должны иметь возможность повторно использовать модуль без каких-либо трудностей. Все в вашей библиотеке (и все, что вы загружаете и добавляете) - это либо модуль, либо пакет модулей.

Например, вы работаете над тем, что читает электронные таблицы, выполняет некоторые вычисления и загружает результаты в базу данных. На что вы хотите, чтобы ваша основная программа выглядела?

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.

Ответ 2

Поскольку нет искусственного предела, это действительно зависит от того, что понятно. Если у вас есть куча довольно коротких простых классов, которые логически сгруппированы вместе, бросьте кучу "em". Если у вас есть большие, сложные классы или классы, которые не имеют смысла как группа, пойдите один файл в класс. Или выберите что-нибудь между ними. Рефакторинг по мере изменения вещей.

Ответ 3

Все зависит от того, насколько велик проект, насколько длительны классы, если они будут использоваться из других файлов и т.д.

Например, я довольно часто использую серию классов для абстракции данных - поэтому у меня может быть 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 содержит полезную информацию об организации пакетов.

Ответ 4

Мне нравится модель Java по следующей причине. Размещение каждого класса в отдельном файле способствует повторному использованию, делая классы более удобными для просмотра при просмотре исходного кода. Если у вас есть группа классов, сгруппированных в один файл, другим разработчикам может быть не очевидно, что там есть классы, которые можно повторно использовать, просматривая структуру каталога проекта. Таким образом, если вы думаете, что ваш класс может быть повторно использован, я бы поместил его в свой собственный файл.

Ответ 5

Я нахожу, что раскалываю вещи, когда меня раздражает объемность файлов и когда естественная закономерность начинает возникать. Часто эти два этапа, похоже, совпадают.

Это может быть очень неприятно, если вы рано разобщите вещи, потому что вы начинаете понимать, что требуется совсем другое упорядочение структуры.

С другой стороны, когда какой-либо файл .java или .py достигает более чем 700 строк, я начинаю раздражаться, постоянно пытаясь запомнить, где "этот конкретный бит".

С Python/Jython циклическая зависимость операторов импорта также, похоже, играет определенную роль: если вы попытаетесь разделить слишком много взаимодействующих базовых строительных блоков на отдельные файлы, это "ограничение" / "несовершенство" языка, похоже, заставляет вас группировать вещи, возможно, довольно разумным образом.

Что касается разделения на пакеты, я действительно не знаю, но, я бы сказал, вероятно, такое же правило раздражения и появления счастливой структуры работает на всех уровнях модульности.

Ответ 6

Я бы сказал, чтобы положить столько классов, сколько может быть логически сгруппировано в этот файл, не делая его слишком большим и сложным.