Чи вважається Pythonic кількома класами, визначеними в одному файлі?


31

Уперше працюючи з python, я виявив, що я закінчую записом декількох класів у один і той же файл, що протистоїть іншим мовам, таким як Java, який використовує один файл у класі.

Зазвичай ці класи складаються з 1 абстрактного базового класу з 1-2 конкретними реалізаціями, використання яких незначно відрізняється. Я опублікував один такий файл нижче:

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 чи для будь-якої мови? Які проблеми можуть виникнути при використанні цієї реалізації, якщо така є?

EDIT: Я не дуже шукаю вказівки щодо цього конкретного файлу, але в більш загальному сенсі. Що робити, якщо заняття виявились 3-5 помірно складними методами? Чи було б тоді сенсом їх розділити? Де вирізається повідомлення про те, що ви повинні розділити файл?


3
Обмеження одного класу на файл НЕ є річчю C ++. Java - єдина мова, яку я знаю, де вважається, чого слід уникати. У C ++ надзвичайно часто для одного файлу .h / .cpp є один первинний клас та безліч допоміжних класів, які можуть бути, а можуть і не бути приватними для основного класу.
Gort the Robot

@StevenBurnap Я вилучив c ++ як приклад, як ви правильно.
1313

1
Це також робиться в php для полегшення автоматичного завантаження. З іншого боку, в php ви можете чітко оголосити простір імен.
BODO

Відповіді:


24

Все добре. Це добре і в С ++, для довідки.

Розумно поєднувати речі разом є розумною практикою. Уникнення невідповідної зв'язку також є хорошою практикою. Домогтися правильного балансу - це не питання суворих правил, а, ну, досягнення балансу між різними проблемами.

Деякі правила:

  1. Розмір

    Надмірно великі файли можуть бути некрасивими, але це навряд чи так. Потворність - це, мабуть, достатньо вагомий привід розділити файл, але розвиток цього естетичного почуття є значною мірою питанням досвіду, тому це не допоможе вам зрозуміти, що робити апріорі

  2. Розмежування проблем

    Якщо ваші конкретні реалізації мають різні внутрішні проблеми, ваш єдиний файл накопичує всі ці проблеми. Наприклад, реалізація залежностей, що не перекриваються, робить ваш єдиний файл залежним від об'єднання всіх цих залежностей.

    Отже, іноді може бути розумним вважати зв'язок підкласів до їх залежностей переважає їх зв'язок із інтерфейсом (або, навпаки, стурбованість реалізацією інтерфейсу слабша, ніж внутрішні стосунки до цієї реалізації).

    В якості конкретного прикладу візьмемо загальний інтерфейс бази даних. Конкретні реалізації з використанням БД пам'яті, SQL RDBMS та веб-запиту відповідно можуть не мати нічого спільного, крім інтерфейсу, і змусити всіх, хто хоче, щоб легка версія пам’яті також імпортувала бібліотеку SQL, противно.

  3. Інкапсуляція

    Хоча ви можете записувати добре інкапсульовані класи в один модуль, це може заохочувати непотрібне з'єднання лише тому, що у вас є доступ до деталей реалізації, які в іншому випадку не могли б експортуватися за межі модуля.

    Думаю, це просто поганий стиль, але ви могли б забезпечити кращу дисципліну, розділивши модуль, якщо дійсно не зможете зламати звичку.


2
Ваша відповідь була б сильнішою, якби вона наводила зовнішні посилання, що демонструють нормальність поєднання класів в одному файлі, або надаючи більше пояснень із зазначенням того, чому це нормально.

1
Я відредагував запитання, щоб зазначити, що це просто приклад того, що я маю на увазі, і не точно відповідає характеру питання. Чому зберігати їх у одному файлі краще, ніж просто імпортувати їх там, де потрібно?
1313

Мати багато крихітних файлів може бути настільки складно керувати, як мати кілька гігантських файлів. Python - досить лаконічна мова. Ваш приклад це показує. Ці три класи безпосередньо пов’язані між собою і, ймовірно, вміщуються в одному вікні редактора без прокрутки.
Gort the Robot

1
@ GlenH7 - Я не впевнений у використанні посилань, оскільки вони просто переходять від мене, подаючи претензію безпосередньо, до мене, стверджуючи, що мій ухил відбору справедливий. Натомість я намагався зосередитись на поясненні.
Марно

7

Мої звичні довідкові документи, щоб знати, що таке пітонічне.

Простий - краще, ніж складний.

Квартира краще, ніж вкладена.

Із Дзен Пітона

Практично без винятку назви класів використовують умову CapWords.

Імена пакетів та модулів Модулі повинні мати короткі, малі імена. [...] Назви модулів відображаються на імена файлів

Від PEP 8

Моя інтерпретація полягає в тому, що це добре, оскільки це дозволить зробити речі простими і рівними. Крім того, оскільки назви класів та імена файлів мають різні випадки, вони все одно не повинні бути однаковими, тому я не побачив би жодної проблеми в упаковці декількох пов'язаних класів у файл.


7
Чи можете ви звести це до тих частин, які стосуються питання? Я читав обидва ці багато разів, але мені важко вибрати, які саме частини стосуються мого поточного питання.
1313

1
Справді, я відредагував свою відповідь.
SylvainD

1

Те, що у вас зараз, - добре. Перейдіть і перегляньте стандартну бібліотеку - в одному файлі є безліч модулів з декількома пов'язаними класами. У якийсь момент все стає більше, і ви, зрештою, захочете почати використовувати модулі з декількома файлами, але немає реальних правил, коли. Речі просто розбиваються, коли один файл починає відчувати себе "занадто великим".


0

Це, безумовно, добре, і я б закликав вас мати кілька класів в одному файлі, якщо вони реалізовані. Як правило, ваші заняття повинні залишатися короткими та стислими, і вам слід скоріше розділити поведінку на два чи більше класів, ніж будувати величезні монолітні. При написанні декількох невеликих класів дійсно необхідно і корисно зберегти ті, що пов'язані в одному файлі.


-1

Словом - пекло так.

Більше того, мати кілька класів в одному файлі іноді дуже зручно. Деякі пакети ( six, bottle) явно постачаються в один файл, щоб легко інтегруватися в будь-який сторонній модуль, не встановлюючи pip (іноді бажано). Але обов'язково добре впорядкуйте свій код. Інтенсивно використовуйте коментарі до коду та блоки розділення, щоб зробити його більш читабельним.


3
це, мабуть, не додає нічого істотного в порівнянні з попередньою відповіддю, опублікованою кілька років тому
gnat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.