выбор между модулями и классами
Вопрос
В моем приложении мне нужно поддерживать некоторые глобальные состояния приложения и глобальные методы приложения, такие как подключенные в данный момент пользователи, общее количество ответов, создание файла конфигурации приложения и т. д.Есть два варианта:
Создайте отдельный файл appstate.py с глобальными переменными и функциями над ними.Сначала все выглядит нормально, но кажется, что я пропал что-нибудь в ясности моего кода.
Создайте класс AppState с функциями класса в файле appstate.py, все остальные модули определяются своими конкретными заданиями.Это выглядит нормально.Но теперь мне нужно написать более длинную строку, например appstate.AppState.get_user_list().Причем методы не так уж сильно связаны друг с другом.Я могу создать отдельные классы, но это будет слишком много классов.
РЕДАКТИРОВАТЬ:Если я использую классы, я буду использовать методы классов.Я не думаю, что есть необходимость создавать экземпляр класса для объекта.
Решение
Второй подход кажется лучше.Я бы использовал первый только для файлов конфигурации или чего-то еще.
В любом случае, чтобы избежать проблемы, вы всегда можете:
from myapp.appstate import AppState
Таким образом, вам больше не придется писать длинную строку.
Другие советы
Звучит как классическая головоломка :-).
В Python нет ничего грязного или постыдного в использовании модуля, если это лучший подход.В конце концов, модули, функции и тому подобное, по сути, являются первоклассными элементами языка и предлагают самоанализ и свойства, которые многие другие языки программирования предлагают только за счет использования объектов.
То, как вы описали свои варианты, похоже на то, что в данном случае вы не слишком без ума от подхода на основе классов.
Я не знаю, использовали ли вы инфраструктуру Django, но если нет, посмотрите документацию о том, как она обрабатывает настройки.Они распространяются на все приложение, определены в модуле и доступны глобально.То, как он анализирует параметры и предоставляет их глобально, довольно элегантно, и вы можете найти такой подход вдохновляющим для ваших нужд.
Второй подход существенно отличается от первого только в том случае, если состояние приложения хранится в файле. пример AppState, и в этом случае ваша жалоба не применима.Если вы просто храните данные в классе и используете статические методы/методы класса, ваш класс ничем не отличается от модуля, и вместо этого было бы питонично иметь его как модуль.
Почему бы не использовать экземпляр этого класса?Таким образом, позже вы сможете запустить два разных «сеанса», в зависимости от того, какой экземпляр вы используете.Возможно, это сделает его более гибким.Может быть, добавить какой-нибудь метод get_appstate()
в модуль, чтобы он один раз создал экземпляр класса.Позже, если вам может понадобиться несколько экземпляров, вы можете изменить этот метод, чтобы он в конечном итоге принимал параметр и использовал некоторый словарь и т. д.для хранения этих экземпляров.
Кстати, вы также можете использовать декораторы свойств, чтобы сделать вещи более читабельными и иметь возможность хранить их так, как и где вы хотите.
Я согласен, что было бы более питонично использовать модульный подход вместо методов класса.
Кстати, я не такой уж большой поклонник того, чтобы вещи были доступны по всему миру с помощью какой-то «магии».Я бы предпочел использовать какой-нибудь явный вызов для получения этой информации.Тогда я знаю, откуда что-то берется и как его отладить, если что-то не получается.
Рассмотрим этот пример:
configuration
|
+-> graphics
| |
| +-> 3D
| |
| +-> 2D
|
+-> sound
Настоящий вопрос:В чем разница между классами и модулями в этой иерархии, поскольку ее можно представить обоими способами?
Классы представляют типы.Если вы реализуете свое решение с помощью классов вместо модулей, вы сможете проверить правильность типа графического объекта, но при этом написать общие графические функции.
С помощью классов вы можете генерировать параметризованные значения.Это означает, что можно инициализировать по-разному звуки класс с конструктором, но инициализировать модуль с разными параметрами сложно.
Дело в том, что вы действительно нечто иное с точки зрения моделирования.
Я бы выбрал путь классов, поскольку он лучше организует ваш код.Помните, что для удобства чтения вы можете сделать это:
from appstate import AppSate
Я бы однозначно выбрал второй вариант:уже использовав первый, теперь я вынужден провести рефакторинг, поскольку мое приложение развивалось и должно поддерживать больше модульных конструкций, поэтому теперь мне нужно обрабатывать несколько одновременных «конфигураций».
Второй подход, по моему мнению, более гибкий и перспективный.Чтобы избежать более длинных строк кода, вы можете использовать from appstate import AppState
вместо того, чтобы просто import appstate
.