python DictReader子类化

2024-04-26 07:20:10 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我关于子类化的第一次尝试,所以我需要你们专家的一些提示。。 我正在尝试子类化csv.DictReader/作者需要一个更高级别的类来做这样的事情:

a = CsvRdr('filename.csv')

for row in a.rows:
    # do something with dict returned in row

a.close()

我想出了一个这样的子类:

^{pr2}$

但当我这么做的时候:

for i in a.rows:
    print i

它返回包含分隔符作为键的未格式化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 

而不是包含正确字段名和由分隔符分隔的相对值的dict

但当我要从另一个函数实例化DictReader时,我需要做的就是:

fo = open(filename, 'rb')
reader = csv.DictReader(fo, delimiter='\t')

reader对象正确地提供了所需的输出。在

有什么建议吗? 我不清楚子类化的过程,我在网上找到的东西对我没有帮助。在

TIA公司 恩里科


Tags: csvinshareforfilenamedictshowsrows
2条回答

最后,我这样解决了:

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()

此函数调用的类:

^{pr2}$

在第二次尝试中,我添加了iter魔术方法来模拟Csv.DictReader,这样您就可以用通常的方式遍历数据,而不是使用对象.行方法:

reader = CsvRead(catalog)
seriesnames = [ row['seriesname'].lower() for row in reader ]
reader.close()

您发布的代码将用AttributeError来填充,而您的意思是拥有self._delim,那么您就拥有了{}。在

除此之外,您的另一个问题是错误地调用构造函数:

self.rows = csv.DictReader(self.__fo, self.__delim)

应该是

^{pr2}$

查看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,这是因为您使用的这个模式实际上是委派而不是子类化或继承。您只需将其中一个objects属性设置为您感兴趣的类的实例,而您的方法只是以更方便的方式调用该实例的方法。在

相关问题 更多 >