2013-08-17 129 views
4

我只是在20年的差距後重新開始編程。我認爲Python看起來相當直接和強大,所以我完成了在線課程和一些閱讀。Python面向對象的設計概念

我現在正在看一些簡單的項目,以熟悉該語言。其中一個挑戰就是讓我的頭腦圍繞着面向對象的編程,而當我最後編寫一個程序時,它並不在我身邊。

我的第一個項目是讀取包含股票投資組合信息的數據文件,對每個項目進行一些計算並打印報告。我有這個工作。

所以現在我正在尋找更高級的東西,閱讀數據並存儲它,然後使用數據爲互動問題提供答案。我的問題是如何存儲數據,以便可以輕鬆訪問。

我首先想到的是讓一個列表的列表,如

companies = [ ['AMP', 1000, 2.50], ['ANZ', 2000, 17.00], ['BHP', 500, 54.30] ] 

這可以在循環很輕鬆地訪問,但是訪問方法都算不上友好 - 數字作爲指標而不是名稱:

companyqty = companies[1][1] 

或者for循環:

for company in companies: 
    if company[0] == 'BHP': 
     companyqty = company[1] 

然後我想到了一本字典,與價值列表:

companies = {'AMP':[1000, 2.50], 'ANZ':[2000, 17.00], 'BHP':[500, 54.30] } 
companyqty = companies['BHP'][0] 

這提供了即時訪問任何給定的公司,但仍然堅持與數字指標。

所以我想知道如何以面向對象的方式來構造這個結構,以便能夠保存公司列表和所有關聯的數據,並且能夠方便地訪問這些值。到目前爲止,我所有的想法都像上面的列表或字典一樣。或者這種問題不是真的適合面向對象的方法嗎?

感謝

回答

4

這是OOP方法的一個很好的問題。例如,您可以爲特定投資組合股票持有創建一個類別,該類別具有公司名稱,股份數量和股價的屬性。你可以給它有用的功能,如getValue。下面是一個示例實現:

class Holding: 
    def __init__(self, companyName, numShares, sharePrice): 
     self.companyName = companyName 
     self.numShares = numShares 
     self.sharePrice = sharePrice 
    def getValue(self): 
     return self.numShares * self.sharePrice 

portfolio = {'AMP':Holding('AMP', 1000, 2.5), 'ANZ':Holding('ANZ', 2000, 17.0), 'BHP':Holding('BHP', 500, 54.30)} 

print portfolio['BHP'].sharePrice 
# 54.3 
print portfolio['AMP'].getValue() 
# 2500.0 

您可以通過屬性名稱訪問您持有的屬性。你可以把它提升到一個新的水平,併爲投資組合編寫一個類,它可能具有諸如「holdingList」和「broker name」之類的屬性,以及諸如「getTotalValue」之類的函數等等。

3

你下一步可以使用與collections.namedtuple() factory產生的一類:

from collections import namedtuple 

Company = namedtuple('Company', 'quantity price') 

companies = {'AMP': Company(1000, 2.50), 'ANZ': Company(2000, 17.00), 'BHP': Company(500, 54.30)} 

companies['AMP'].quantity 

注意,喜歡tuple對象,namedtuple衍生的對象是不可改變的。您不能指定屬性,而是創建一個新對象。

如果您需要爲對象添加功能,則只需切換到自定義類;添加作用於與對象關聯的數據的方法:

class Company(object): 
    def __init__(self, quantity, price): 
     self.quantity = quantity 
     self.price = price 

    def profit(self, newprice): 
     return self.quantity * (newprice - self.price) 
1

你也可以使用嵌套的字典:

companies = 
    { 
     'AMP': {'quantity':1000, 'price': 2.50}, 
     'ANZ': {'quantity':2000, 'price': 17.00}, 
     'BHP': {'quantity':500, 'price': 54.30} 
    } 

和訪問它想:

companyqty = companies['BHP']['quantity'] 

,你甚至可以定義額外的 「屬性」 公司:

companies = 
    { 
     'AMP': {'quantity':1000, 'price': 2.50, 'foundation_date': '2013-01-01'}, 
     'ANZ': {'quantity':2000, 'price': 17.00}, 
     'BHP': {'quantity':500, 'price': 54.30, 'head': 'Jeffrey'} 
    } 
0

即使如此在Python中,只有一種方法可以做到,這個問題的答案實際上取決於什麼是「可以訪問」 sed容易「。

這是否意味着程序員訪問對象很容易,它的屬性?那麼最好的辦法就是讓公司成爲一個類的實例,併爲價格,數量等提供屬性。可能,把類叫做投資組合是一件很矯枉過正的事,除非你的列表或字典的邏輯不同。也可以基於字典創建類,因此可以通過鍵和屬性進行訪問。這就是我所稱的訪問輕鬆。以Webpy框架的Storage類爲例:https://github.com/webpy/webpy/blob/master/web/utils.py#L52爲例。

如果「容易訪問」意味着第三方庫將對數據進行一些序列化或其他處理,那麼最簡單的方法是使用庫預期的數據結構。例如,JSON格式與Python的列表和字典非常吻合(請參閱Roman Pekar的答案)。

+0

我想我真正的意思是以最小化錯誤可能性的方式訪問,特別是使用數字引用字段(例如Companies [1] [1])。在我的第一個練習中,我多次出手。我想我仍然在考慮從1開始而不是從0開始的索引。通過使用名稱,我避免了這種情況。 –

+0

是的,我甚至沒有考慮過使用數字鍵,因爲使用鍵或屬性會使格式攜帶它的上下文。如果出於某種外部原因必須使用列表或元組中的位置,則可以爲位置定義名稱,例如,公司[0] [COMPANY_PRICE。在其中一個答案中也提到了名稱。 –