Pythonic способ организации модулей и пакетов - PullRequest
41 голосов
/ 26 ноября 2009

Я пришел из фона, где я обычно создаю один файл на класс. Я также организую общие классы по каталогам. Эта практика для меня интуитивно понятна и доказала свою эффективность в C ++, PHP, JavaSript и т. Д.

У меня проблемы с переносом этой метафоры в Python: файлы больше не просто файлы, а формальные модули. Кажется неправильным просто иметь один класс в модуле - большинство классов сами по себе бесполезны. Если у меня есть класс automobile.py и Automobile, кажется глупым всегда ссылаться на него как automobile.Automobile.

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

Каков правильный или питонический путь? (Или, если нет правильного пути, какой путь вы предпочитаете и почему?) Сколько кода я должен добавить в модуль Python?

Ответы [ 5 ]

32 голосов
/ 26 ноября 2009

Думайте в терминах «логической единицы упаковки» - которая может быть одним классом, но чаще будет набором классов, которые тесно взаимодействуют. Классы (или функции уровня модуля - не «делайте Java в Python», всегда используя статические методы, когда функции уровня модуля также доступны для выбора! -) могут быть сгруппированы на основе этого критерия. По сути, если большинству пользователей A также требуется B и наоборот, A и B, вероятно, должны находиться в одном модуле; но если многим пользователям нужен только один из них, а не другой, то они, вероятно, должны быть в разных модулях (возможно, в одном пакете, то есть в каталоге с файлом __init__.py).

Стандартная библиотека Python, хотя и далека от совершенства, имеет тенденцию отражать (в основном) достаточно хорошие практики - так что вы можете в основном учиться на ней на примере. Например, модуль threading, конечно, определяет класс Thread ... но он также содержит классы синхронизации примитивов, такие как блокировки, события, условия и семафоры, и класс исключений, который может быть вызван операциями потоков (и еще несколько вещей). Он находится на верхней границе разумного размера (800 строк, включая пробелы и строки документов), и некоторые важные функции, связанные с потоками, такие как очередь, помещены в отдельный модуль, тем не менее, это хороший пример того, какой максимальный объем функций по-прежнему имеет смысл упаковать в один модуль.

9 голосов
/ 26 ноября 2009

Если вы хотите придерживаться своей системы «один класс на файл» (что логично, не поймите меня неправильно), вы можете сделать что-то подобное, чтобы избежать обращения к automobile.Automobile:

from automobile import Automobile
car = Automobile()

Однако, как упоминает cobbal, в Python довольно распространено более одного класса на файл. В любом случае, пока вы выбираете разумную систему и используете ее последовательно, я не думаю, что пользователи Python будут злиться на вас:).

8 голосов
/ 26 ноября 2009

Если вы исходите из точки зрения c ++, вы можете просматривать модули python, похожие на .so или .dll. Да, они выглядят как исходные файлы, потому что Python написан на скрипте, но на самом деле это загружаемые библиотеки с определенной функциональностью.

Еще одна метафора, которая может помочь, - вы можете рассматривать модули python как пространства имен.

4 голосов
/ 26 ноября 2009

В проекте среднего размера я обнаружил несколько наборов тесно связанных классов. Некоторые из этих наборов теперь сгруппированы в файлы; например, все низкоуровневые сетевые классы находятся в одном модуле network. Тем не менее, некоторые из самых больших классов были разделены на свои собственные файлы.

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

3 голосов
/ 26 ноября 2009

В качестве расплывчатого указания: более 1 класса на файл является нормой для python

также см. Сколько классов Python я должен поместить в один файл?

...