2011-06-09 53 views
3

我刚刚开始使用Python和编程,我对存储许多对象有一个普遍的疑问。OOP和Python新手 - 关于存储大量对象的问题

我至今对象的理解是这样的:我可以定义一个对象,如:

class Meal: 

而且有它的功能,这样我可以了解它例如Meal.drink回报汽水'和Meal.main返回'披萨'。到现在为止还挺好。

但是,我不确定我在存储大量对象时做了正确的事情。现在,我让他们都在一个列表,这样我每次想录制新饭我做的:

temp = Meal() 

listOfMeals.append(temp) 

如果我想找出有多少次我已经苏打所有记录下来的食物,我遍历列表并计数:

for each in listOfMeals 

    if each.drink == 'soda': 

     sodaCount = sodaCount + 1 

这是处理长对象列表的最佳方法吗?这对我来说有点笨拙,但由于我没有使用面向对象编程的经验(而且一般编程经验很少),我不确定是否忽略了某些明显的东西。

谢谢你的帮助。

+0

你可以使用'listOfMeals.append(Meal())'而不是创建一个临时对象。 – tMC 2011-06-09 17:28:21

+0

你有正确的想法。这里唯一的变体是你如何实现这个想法(你选择或不使用的variou python)。 – inspectorG4dget 2011-06-09 17:30:03

+0

下面有一些聪明的解决方案,但是除非速度对您的程序来说是个问题,否则您的解决方案就没有问题。 – Jeff 2011-06-09 17:54:50

回答

0

你的代码没有问题。这不是很习惯但很好。如果你对缓慢没有任何问题,只要用你写的这种方式来使用它。

1

使用ORM(例如SQLAlchemy)将允许您将所有这些存储在数据库中,这可以帮助加快某些类型的查询(“查找饮料属性为'汽水'的所有餐点。”)。

1

你也可以用“功能”风格编写计数循环,那么你甚至不需要sodaCount var。

def count_sodas(meals): 
    return reduce(lambda count, meal: count + (1 if meal.drink == 'soda' else 0), 
       meals, 0) 
6

这取决于你要做什么。 每个一段代码可以更有效地写入,但首先应该问自己的问题是:为什么此代码必须更快?

如果没有理由作出这样的方法更快(因为计数不使用那么多,吃饭的名单刚刚一百项不管怎么说,等等),你应该去一些简单的像

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'] 
+0

+1用于确定是否需要优化优先。 – 2011-06-09 18:04:07

0

你有正确的想法。这里有几点我想提出:

  1. 当定义一个类时,“继承”从对象(或其他类),因此class Meal(object):
  2. 你说drinkmain的功能。如果是,请确保在要引用返回值时调用它们。meal.drink == 'soda'应该是meal.drink() == 'soda'
  3. 除非这些膳食属性有一个很好的理由是一个函数(即你需要计算它们),否则它们应该是简单的Meal对象的“实例属性”。

如果你发现有一些常用的操作,你需要的饭菜列表执行它可能是有用的包餐的清单,自定义对象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

'meal.drink()=='soda''?你确定这就是你的意思吗? – 2011-06-09 18:29:16

+0

是的,如果作为OP说Meal.drink是一个“功能”。当然,那不是很好的代码。我的意思是,如果他们真的是可以召唤的,他们需要被召唤。 – 2011-06-09 18:33:33