2013-05-28 3 views
0

Какова хорошая конструкция класса, который будет обрабатываться как служба: он инициализирует большие данные на диске и затем отвечает на запросы от другого модуля?Python-класс как услуга

Может ли это быть класс со статическими данными? Данные загружаются с диска, вызывая функцию Init, после чего можно запросить класс.

Не могли бы вы, пожалуйста, критиковать это решение? Не могли бы вы предложить что-то лучше?

+0

Было бы проще прокомментировать вашу идею, если вы нарисуете ее несколькими строками кода. –

ответ

2

Из вашего описания Я понимаю, что вы предлагаете читать все данные с диска в члены экземпляра класса или аналогичные (я бы не использовал глобальные модули модулей, если это то, что вы планируете), а затем отвечаете на запросы, используя что данные - правильно ли я вас понял?

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

Если возможно, возможно, лучше прочитать данные с диска по требованию, возможно, с некоторым кэшированием в памяти, если это необходимо. Я бы предложил разместить ваши данные в структурированном формате, если вы можете, что-то вроде SQLite - довольно простой способ создания структурированных данных файла. Затем вы можете писать методы, которые выполняют SQL-запросы для восстановления данных из файла по мере необходимости.

Если вам нужно повысить производительность, кэшируя общие результаты в памяти, вы можете использовать что-то вроде декоратора Python 3 LRU cache вокруг всех функций, которые вы хотите кэшировать. Это предполагает, что результаты функции зависят только от ее аргументов. Если вы используете Python 2.x, вы можете найти implementations for that too, хотя и не в стандартной библиотеке.

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

Ответит ли это на ваш вопрос, или я пропустил это? Просьба представить разъяснения, если вам нужен другой ответ.

EDIT

После ваш комментарий ниже, я думал, что я хотел бы добавить немного больше разъяснений.

Во-первых, я не совсем уверен, что вы подразумеваете под «статическими» данными. Python действительно не имеет этой концепции так же, как что-то вроде C/C++ или Java. Вы можете иметь атрибуты класса, которые хранятся в объекте класса и доступной для случаев, как если бы они были обычными атрибутами:

class MyClass(object): 

    class_attribute = 123 

    def method(self): 
     print "Class attribute value: %d" % (self.class_attribute,) 

... Но в данном случае я не думаю, что это хорошая идея. Возможно, с помощью «статического» вы просто подразумеваете совокупность данных, хранящихся в качестве атрибутов экземпляра класса, и если это так кажется совершенно разумным вариантом для того, что вы описываете.

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

Возьмем простой пример, если ваш класс хранения строк из файла, то вы можете иметь:

class FileLines(object): 

    def __init__(self, filename): 
     self.lines = [] 
     self.load_file(filename) 

    def load_file(self, filename): 
     with open(filename, "r") as fd: 
      self.lines = [i.rstrip() for i in fd] 

(Я понимаю, что установка lines в __init__() не является строго обязательным, поскольку он сбрасывается в load_file(), но я думаю, что это хорошая практика, чтобы инициализировать все атрибуты в __init__()).

Это, безусловно, довольно бессмысленный класс, но вы получаете идею - прочитайте данные от __init__(), а затем сделайте это доступным. Кстати, я совершенно не намеренно не добавлял метод «getter» для атрибута lines. В Python вполне приемлемо напрямую обращаться к атрибутам, нет необходимости в методах «getter» и «setter», которые вы часто видите в C/C++ и Java , Это связано с тем, что вы можете использовать properties в Python для замены простых атрибутов методами позже, если вам нужно реализовать более сложные функции. Таким образом, теперь вы можете иметь простоту базовых атрибутов с гибкостью и в дальнейшем.

Кроме того, предполагая, что ваши данные имеют структуру, вы должны подумать о том, как вы ее храните. Словари, списки и наборы очень мощные в Python, но если ваши данные имеют именованные поля, подумайте об использовании collections.namedtuple или пользовательского класса для его представления. Это делает его более удобным (и, следовательно, менее подверженным ошибкам) ​​для пользователей класса для доступа к нему. В идеале я бы предложил попытаться сохранить представление в памяти объекта в одном классе и иметь код для анализа представления на диске в другом месте, который создает экземпляры версии в памяти. Сохранение различий в представлениях позволит вам изолировать пользователей вашего класса от изменений в представлении на диске.

Надеюсь, это помогло.

+0

Спасибо за ответ! Да, вы поняли меня правильно. Кажется, что я могу читать все данные в памяти, большие данные сами по себе здесь не проблема. Этот вопрос больше связан с архитектурой класса. Должны ли они содержать статические данные? Должен ли он иметь метод Init? – typedef

Смежные вопросы