2013-05-28 30 views
0

類將被視爲服務的良好設計是什麼:它從磁盤上的大數據初始化,然後響應來自另一個模塊的請求?作爲服務的Python類

它可以只是靜態數據類嗎?通過調用Init函數從磁盤加載數據,然後可以爲該類發出請求。

你能批評這個解決方案嗎?你會提出更好的建議嗎?

+0

如果您用幾行代碼勾勒出您的想法,對它進行評論會更容易。 –

回答

2

從你的描述我明白,你建議讀取所有的數據從磁盤到類實例或類似的成員(我不會使用模塊全局變量,如果這是你的計劃),然後響應請求使用那些數據 - 我能正確理解你嗎?

只要系統中有足夠的內存,這種方法就可以正常工作 - 因爲我不知道數據有多大,所以我不能評論這是否現實。但是,您對代碼施加了可伸縮性限制,因此如果數據變得越來越大,則可能會導致代碼運行速度非常緩慢或導致崩潰。不同的平臺對內存耗盡的反應略有不同,但結果幾乎總是不太合理。

如果可能,最好從磁盤上按需讀取數據,如果適用的話,可能會使用一些內存中緩存。如果可以,我建議將數據轉換爲結構化格式,例如SQLite是創建結構化文件數據的一種相當簡單的方法。然後,您可以編寫執行SQL查詢的方法,以根據需要從文件中恢復數據。

如果你需要通過在內存中緩存常見結果來獲得更好的性能,你可以在你想要緩存的所有函數中使用像Python 3的LRU cache修飾器。這確實假定函數的結果僅依賴於它的參數。如果您使用的是Python 2.x,那麼您可以找到implementations for that too,但不在標準庫中。

如果您的結果依賴於類成員以及函數參數,那麼您可能需要編寫自己的緩存層或使用上述解決方案並手動清除緩存成員改變。我不能不知道更多關於您的問題的細節,但希望涵蓋所涉及的問題。

這是回答你的問題,還是我錯過了觀點?如果您需要不同的答案,請提供澄清。

編輯

下面的評論後,我想我會添加一些澄清。首先,我並不完全明白「靜態」數據的含義 - 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] 

(我認識到,設置在__init__()lines沒有嚴格要求,因爲它在load_file()復位,但我認爲最好初始化__init__()中的所有屬性)。

這顯然是一個毫無意義的課程,但您明白了 - 從__init__()讀取數據,然後使其可用。順便說一下,我非常故意沒有爲lines屬性添加「getter」方法 - 在Python中,直接訪問屬性是完全可以接受的,不需要在C/C++和Java中經常看到的「getter」和「setter」方法。這是因爲如果您需要實現更復雜的功能,則可以在Python中使用properties以便用方法替換簡單屬性。因此,您現在可以擁有基本屬性的簡單性,並且具有以後的靈活性。

此外,假設您的數據具有結構,您應該考慮一下如何存儲它。字典,列表和集合在Python中都非常強大,但是如果您的數據已經命名了字段,那麼請考慮使用collections.namedtuple或自定義類來表示它。這使得該類的用戶可以更方便地訪問它(並因此更容易出錯)。理想情況下,我會建議嘗試將對象的內存中表示保留在一個類中,並讓代碼解析其他地方的磁盤表示,從而生成內存版本的實例。以這種方式保持表示的獨立性將允許您將您的課程的用戶與磁盤上表示的變化隔離開來。

希望這有一些幫助。

+0

感謝您的回答!是的,你正確理解我。看起來我可以將所有數據讀入內存,大數據本身在這裏不成問題。這個問題更多的是關於班級的架構。它是否應該包含靜態數據?它應該有Init方法嗎? – typedef