2017-08-25 105 views
0

我寫一個CSV解析器具有以下結構解析CSV有效地蟒蛇

class decode: 
def __init__(self): 
    self.fd = open('test.csv') 


def decodeoperation(self): 
    for row in self.fd: 
     getcmd = self.decodecmd(row) 
     if cmd == 'A' 
      self.decodeAopt() 

     elif cmd == 'B': 
      self.decodeBopt() 

def decodeAopt(self): 
    for row in self.fd: 
     #decodefurther dependencies based on cmd A till 
     #a condition occurs on any further row 

    return 
def decodeBopt(self): 
    for row in self.fd: 
     #decodefurther dependencies based on cmd B till 
     #a condition occurs on any further row 
    return 

目前的代碼工作爲我好,但我不覺得好通過CSV文件中的所有方法進行迭代。它能以更好的方式完成嗎?

回答

2

在多個方法中使用通用迭代器沒有任何內在的錯誤,只要您可以提前確定在序列中的任何給定點分派哪個方法(您正在通過從行解碼cmd並獲得'A','B'等)。如果在確定要調用哪種方法之前必須先閱讀幾個項目,並且可能必須在選擇了錯誤方法並需要嘗試另一方法時進行備份,則設計會出現問題。在解析中,這被稱爲回溯。由於您傳遞的是文件對象,因此備份很困難。請注意,單獨的解碼器方法在讀取包含命令的下一行之前必須知道何時停止,因此它們需要某種可識別的終止哨兵行。

你的Python和一流的設計一些一般性的評論:

你有一個很好的簡單的if-elif的 - elif的調度表,可以轉化爲Python字典是這樣的:

# put this code in place of your "if cmd == ... elif elif elif..." code 
dispatch = { 
    # note - no()'s, we just want to reference the methods, not call them 
    'A': self.decodeAopt, 
    'B': self.decodeBopt, 
    'C': self.decodeCopt, 
    # look how easy it is to add more decoders 
} 

# lookup which decoder to use for the current cmd 
decoder = dispatch[cmd] 

# run it 
decoder() 

# or do it all in one line 
dispatch[cmd]() 

而是具有你的__init__方法打開一個文件,讓它接受一個迭代器對象。這樣可以更輕鬆地爲對象編寫測試,因爲您可以傳遞包含CSV行的簡單Python列表。

class decode: 
    def __init__(self, sequence): 
     self.fd = sequence 

您可能希望從「的fd」這無功重命名爲類似「序列」,因爲它不必是一個文件,但可以是任何可迭代的,讓你解碼行。

如果您正在做自己的CSV解析,請查看使用內置的csv模塊。它會爲你做相當多的工作,比如解析可能包含逗號的引用字符串,並且可以爲每行提供易於使用的字典,給定的頭文件可以從輸入文件讀取,或由您指定。如果你已經修改__init__我建議,你可以用它喜歡:

cmd = row['cmd'] 

請注意,這將賦予略有不同的設計類,即:

import csv 

# assuming test.csv has a header row 
reader = csv.DictReader(open('test.csv')) 

# or specify headers if not - I encourage you to give these columns better names 
reader.fieldnames = ['cmd', 'val1', 'val2', 'val3'] 

decoder = decode(reader) 
decoder.decodeoperation() 

然後你就可以在decodeoperation寫它會期望得到一系列的字符串,而不是一串字符串。

+1

我採取了一些建議,並在我的代碼中實現。它改進了代碼的簡單性並解決了一些維護問題。 – NGB