簡體   English   中英

python DictReader子類化

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM