выбор между модулями и классами - PullRequest
17 голосов
/ 01 марта 2009

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

  1. Создайте отдельный файл appstate.py с глобальными переменными с функциями над ними. Поначалу все выглядит хорошо, но мне кажется, что мне не хватает что-то для ясности моего кода.

  2. Создайте класс AppState с функциями класса в файле appstate.py, все остальные модули определены их конкретными заданиями. Это выглядит хорошо. Но теперь я должен написать более длинную строку, как appstate.AppState.get_user_list (). Более того, методы не столько связаны друг с другом. Я могу создать отдельные классы, но это будет слишком много классов.

РЕДАКТИРОВАТЬ: Если я использую классы, я буду использовать методы класса. Я не думаю, что есть необходимость создавать экземпляр класса для объекта.

Ответы [ 7 ]

23 голосов
/ 01 марта 2009

Звучит как классическая головоломка: -).

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

То, как вы описали свои варианты, звучит так, как будто вы не слишком без ума от подхода, основанного на классах, в этом случае.

Я не знаю, использовали ли вы Django-фреймворк, но если нет, посмотрите документацию о том, как он обрабатывает настройки. Это приложения, они определены в модуле и доступны по всему миру. То, как он анализирует варианты и показывает их глобально, довольно элегантно, и вы можете найти такой подход, вдохновляющий ваши потребности.

5 голосов
/ 01 марта 2009

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

3 голосов
/ 01 марта 2009

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

В любом случае, чтобы избежать проблемы, вы всегда можете:

from myapp.appstate import AppState

Таким образом, вам больше не нужно писать длинную строку.

1 голос
/ 01 марта 2009

Рассмотрим этот пример:

configuration
|
+-> graphics
|   |
|   +-> 3D
|   |
|   +-> 2D
|
+-> sound

Реальный вопрос: в чем разница между классами и модулями в этой иерархии, поскольку она может быть представлена ​​обоими способами?

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

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

Дело в том, что вы действительно чем-то отличаетесь от точки зрения моделирования.

1 голос
/ 01 марта 2009

Почему бы не пойти с экземпляром этого класса? Таким образом, вы можете запустить 2 разных «сессии» в зависимости от того, какой экземпляр вы используете. Это может сделать его более гибким. Возможно, добавьте в модуль какой-нибудь метод get_appstate(), чтобы он один раз создал экземпляр класса. Позже, если вам может понадобиться несколько экземпляров, вы можете изменить этот метод, чтобы в конечном итоге принять параметр и использовать некоторый словарь и т. Д. Для хранения этих экземпляров.

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

Я согласен, что было бы более питонно использовать модульный подход вместо методов классов.

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

0 голосов
/ 01 марта 2009

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

Второй подход, IMO, более гибкий и перспективный. Чтобы избежать более длинных строк кода, вы можете использовать from appstate import AppState вместо просто import appstate.

0 голосов
/ 01 марта 2009

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

from appstate import AppSate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...