2011-06-09 54 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