Новое в ООП и Python - вопрос о хранении большого количества объектов - PullRequest
3 голосов
/ 09 июня 2011

Я только начал изучать Python и программирование, и у меня есть общий вопрос о хранении многих объектов.

Мое понимание объектов до сих пор таково: я могу определить объект как:

class Meal:

И у меня есть такие функции, что я могу узнать об этом, например, Meal.drink возвращает soda, а Meal.main возвращает pizza. Пока все хорошо.

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

temp = Meal()

listOfMeals.append(temp)

Если я хочу узнать, сколько раз я выпивал газировки за все записанные приемы пищи, я перебираю список и считаю:

for each in listOfMeals

    if each.drink == 'soda':

        sodaCount = sodaCount + 1

Это лучший способ обработки длинных списков объектов? Мне это кажется немного неуклюжим, но, поскольку у меня нет опыта объектно-ориентированного программирования (и вообще немного опыта программирования), я не уверен, что упустил что-то очевидное.

Спасибо за любую помощь.

Ответы [ 5 ]

6 голосов
/ 09 июня 2011

Это зависит от того, что вы собираетесь. Каждый фрагмент кода может быть написан более эффективно, но вопрос, который вы всегда должны сначала задать себе: почему этот код должен быть быстрее?

Если нет причин ускорять этот метод (так как счетчик используется не так часто, список блюд в любом случае содержит только сотню записей и т. Д.), Вам нужно просто выполнить что-то простое, например

sodacount = sum(1 for meal in listOfMeals if meal.drink=='soda')

С другой стороны, если вам нужен этот подсчет очень часто, вы можете обернуть свой список блюд в другой объект, который хранит и обновляет счет:

class MealList(object):
    # insert __init__, etc.

    def addMeal(self, meal):
        self._meals.append(meal)
        # update the count
        self.counts[meal.drink] += 1

    # insert method to remove meals

meals = MealList()
# add meals etc ....
print meals.counts['soda']
1 голос
/ 09 июня 2011

Использование ORM, такого как SQLAlchemy , позволит вам хранить все это в базе данных, что затем может помочь ускорить определенные типы запросов («Найти все блюда, где атрибут напитка -« газировка ». «).

1 голос
/ 09 июня 2011

Вы также можете написать цикл подсчета в «функциональном» стиле, тогда вам даже не понадобится sodaCount var.

def count_sodas(meals):
  return reduce(lambda count, meal: count + (1 if meal.drink == 'soda' else 0),
                meals, 0)
0 голосов
/ 09 июня 2011

У вас правильная идея. Я хотел бы сделать несколько замечаний:

  1. При определении класса «наследовать» от объекта (или другого класса), таким образом, class Meal(object):
  2. Вы говорите, что drink и main являются функциями. Если они есть, убедитесь, что вы звоните им, когда хотите сослаться на возвращаемое значение. meal.drink == 'soda' должно быть meal.drink() == 'soda'
  3. Если не существует веской причины для того, чтобы эти атрибуты еды были функцией (т. Е. Вам нужно их вычислять), они, вероятно, должны быть простыми «атрибутами экземпляра» объекта «Питание».

Если вы обнаружите, что в списке блюд есть ряд общих операций, которые вам необходимо выполнить, может быть полезно обернуть список блюд пользовательским объектом Meals. Затем вы можете добавить свои собственные методы. Например, вам может потребоваться регулярно находить все блюда из трех блюд:

class Meals(object):
    def __init__(self):
        self.meals = []
    def __iter__(self):
        return iter(self.meals)
    def three_course(self):
        return [m for m in self.meal if m.starter and m.main and m.dessert]

Это довольно надуманный пример, но вы должны понять. Также обратите внимание, что существует множество способов сделать это; Вы можете разделить список на подклассы, а не переносить его Если вы храните данные о еде в базе данных, подумайте над ответом @Ignacio. SQLAlchemy великолепна и может быть настолько простой или сложной, насколько вам нужно.

0 голосов
/ 09 июня 2011

В вашем коде нет проблем.Это не очень идиоматично, но все в порядке.Если у вас нет проблем с медлительностью, просто используйте ее так, как вы написали.

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