[英]python DictReader subclassing
這是我第一次嘗試進行子類化,因此我需要專家的一些提示。.我正在嘗試將csv.DictReader / Writer子類化以具有更高級別的類來執行以下操作:
a = CsvRdr('filename.csv')
for row in a.rows:
# do something with dict returned in row
a.close()
我想出了一個像這樣的子類:
class CsvRdr(csv.DictReader):
def __init__(self, filename):
self.__fo = open(filename, 'rb')
self.__delim = '\t'
self.rows = csv.DictReader(self.__fo, self.__delim)
self.rows.__init__(self.__fo, self.__del)
def close(self):
self.__fo.close()
但是當我這樣做時:
for i in a.rows:
print i
它返回包含定界符\\ t作為鍵的無格式dict:
{'\t': 'seriesid\tseriesname\tstatus\tquality\tgroup\tpath'}
{'\t': '80337\tMad Men\tAiring\thdtv\tTV Shows\t/share/MD0_DATA/SORT/TV Shows/Mad Men'}
{'\t': '271910\tHalt and Catch Fire\tHiatus\thdtv\tTV Shows\t/share/MD0_DATA/SORT/TV
而不是包含正確的字段名和由定界符分割的相對值的字典
但是,當我要從另一個函數實例化DictReader時,我要做的就是:
fo = open(filename, 'rb')
reader = csv.DictReader(fo, delimiter='\t')
並且Reader對象正確地為您提供了所需的輸出。
有什么建議嗎? 我尚不清楚子類化過程,到目前為止在網上發現的內容對我沒有幫助。
TIA恩里科
您發布的代碼將與BARF AttributeError
,你有self._del
當你想有self._delim
。
除此之外,另一個問題是您錯誤地調用了構造函數:
self.rows = csv.DictReader(self.__fo, self.__delim)
應該
self.rows = csv.DictReader(self.__fo, delimiter = self.__delim)
查看DictReader
的構造函數簽名,我們看到了實際發生的情況:
csv.DictReader(self, f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)
您的self.__delim
參數已設置為fieldnames
參數。 當您為僅保留關鍵字參數的函數提供非關鍵字位置參數時,默認情況下,這就是Python(無論如何為2.7)所做的事情。 它使用位置參數填充簽名中的下一個關鍵字參數。
因此,您告訴DictReader
“嘿,此CSV僅包含一列,名稱為'\\ t'”。 因此DictReader
做邏輯上的事情,即每行只有一個值,該值是整行。
最后這一行:
self.rows.__init__(self.__fo, self.__del)
什么也沒做,您只是在以更明確的方式重復構造函數調用。
這是我將重新編寫您想做的事情的方法:
class CsvRdr(object):
def __init__(self, filename):
self.__fo = open(filename, 'rb')
self.__delim = '\t'
self.rows = csv.DictReader(self.__fo, delimiter = self.__delim)
def close(self):
self.__fo.close()
注意,我將csv.DictReader
更改為object
,這是因為您使用的這種模式實際上是委派,而不是子類化或繼承。 您只是將對象屬性之一設置為您要使用的類的實例,而您的方法只是以更方便的方式調用該實例的方法。
最后,我以這種方式解決了:
class CsvRdr(object):
def __init__(self, filename, delimiter=None):
self.__fo = open(filename, 'rb')
self.__delim = ( delimiter if delimiter else '\t' )
self.__rows = csv.DictReader(self.__fo, delimiter = self.__delim)
def __iter__(self):
return self.__rows
def close(self):
self.__fo.close()
此函數調用的類:
def CsvRead(filename):
try:
reader = CsvRdr(filename)
return reader
except IOError, e:
print "Error reading file : %s ERROR=%s" % (filename, e)
sys.exit(2)
在第二次嘗試中,我添加了iter magic方法來模仿Csv.DictReader的原始行為,因此您可以按常規方式遍歷數據,而不是使用object.rows方法:
reader = CsvRead(catalog)
seriesnames = [ row['seriesname'].lower() for row in reader ]
reader.close()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.