Pythonic способ организации модулей и пакетов
Я пришел из фона, где я обычно создаю один файл на класс. Я также организую общие классы по каталогам. Эта практика для меня интуитивно понятна и доказала свою эффективность в C++, PHP, JavaSript и т. Д.
У меня возникли проблемы с переносом этой метафоры в Python: файлы больше не просто файлы, а формальные модули. Кажется неправильным просто иметь один класс в модуле - большинство классов сами по себе бесполезны. Если у меня есть automobile.py
и Automobile
класс, кажется глупым всегда ссылаться на это как automobile.Automobile
также.
Но, в то же время, кажется неправильным бросать тонну кода в один файл и называть это днем. Очевидно, что очень сложное приложение должно иметь более 5 файлов.
Какой правильный или питонический путь? (Или, если нет правильного пути, какой путь вы предпочитаете и почему?) Сколько кода я должен добавить в модуль Python?
5 ответов
Думайте с точки зрения "логической единицы упаковки" - которая может быть единым классом, но чаще будет набор классов, которые тесно взаимодействуют. Классы (или функции уровня модуля - не "делайте Java в Python", всегда используя статические методы, когда функции уровня модуля также доступны для выбора!-) могут быть сгруппированы на основе этого критерия. По сути, если большинству пользователей A также требуется B и наоборот, A и B, вероятно, должны находиться в одном модуле; но если многим пользователям потребуется только один из них, а не другой, то они, вероятно, должны быть в разных модулях (возможно, в одном пакете, то есть в каталоге с __init__.py
файл в нем).
Стандартная библиотека Python, хотя и далека от совершенства, имеет тенденцию отражать (в основном) достаточно хорошие практики - так что вы можете в основном учиться на ней на примере. Например, threading
Модуль, конечно, определяет Thread
класс... но он также содержит примитивные для синхронизации классы, такие как блокировки, события, условия и семафоры, и класс исключений, который может быть вызван с помощью потоковых операций (и еще нескольких вещей). Он находится на верхней границе разумного размера (800 строк, включая пробелы и строки документации), и некоторые важные функции, связанные с потоками, такие как очередь, помещены в отдельный модуль, тем не менее это хороший пример того, какой максимальный объем функций по-прежнему имеет смысл упаковать в единый модуль.
Если вы хотите придерживаться своей системы "один класс на файл" (что логично, не поймите меня неправильно), вы можете сделать что-то подобное, чтобы избежать обращения к automobile.Automobile
:
from automobile import Automobile
car = Automobile()
Однако, как упоминает cobbal, в Python довольно распространено более одного класса на файл. В любом случае, пока вы выбираете разумную систему и используете ее последовательно, я не думаю, что пользователи Python будут злиться на вас:).
Если вы пришли с точки зрения C++, вы можете просмотреть модули Python, сродни.so или.dll. Да, они выглядят как исходные файлы, потому что Python написан на скриптах, но на самом деле они являются загружаемыми библиотеками определенной функциональности.
Еще одна метафора, которая может вам помочь, - вы можете рассматривать модули Python как пространства имен.
В проекте среднего размера я обнаружил несколько наборов тесно связанных классов. Некоторые из этих наборов теперь сгруппированы в файлы; например, низкоуровневые сетевые классы находятся в одном network
модуль. Тем не менее, некоторые из крупнейших классов были разделены на свои собственные файлы.
Возможно, лучший способ начать этот путь с истории одного класса на файл - это взять классы, которые вы обычно помещаете в один и тот же каталог, и вместо этого хранить их в одном файле. Если этот файл начинает выглядеть слишком большим, разделите его.
В качестве расплывчатого указания: более 1 класса на файл является нормой для Python
также, посмотрите, сколько классов Python я должен поместить в один файл?