New Class没有setItem方法

时间:2013-07-24 17:58:40

标签: python python-2.7

所以,这是我的代码。

def classMaker(csv):
    csv = csv.split("/n")
    firstLine = csv[0]
    csv = csv[1:]
    class newClass():
        def __init__(self, line):
            self.vars = firstLine
            for i in range(len(line)):
                self[firstLine[i]] = line[i]
    return [newClass(line) for line in csv]

问题是self [firstLine [i]] = line [i]中的AttributeError。它说

AttributeError: newClass instance has no attribute '__setitem__'

我不知道为什么会导致此错误。我的目标是接收从Excel导出的csv文件,并从字段名称自动生成对象名称。

提前谢谢。

2 个答案:

答案 0 :(得分:3)

如果您使用collections.namedtuple

,则可以一起避免newClass
CSVRow = namedtuple("CSVRow", firstLine)
return [CSVRow(*line) for line in csv]

这假设CSV标头将是有效的Python标识符(也就是说,如果您有“某些值”这样的内容,如果您不处理firstLine,这将无效。

这可以让你做到这样的事情:

# Let's assume your CSV has a Name field
# and that it is the first column
csv_data[3].Name == csv_data[3][0]
# True

此外,您应该查看csv module以简化CSV处理。

答案 1 :(得分:1)

如果我能正确推断你的意图,你想要替换这一行:

self[firstLine[i]] = line[i]

用这个:

setattr(self, firstline[i], line[i])

这将创建以数据中的列命名的newClass对象的属性。

E.g:

Name, Date, Weight
Joe, 23-Sep, 99
...

data = classMaker('file.csv') 

将产生:

data[0].Name == 'Joe'

P.S。我假设您将添加文件I / O,解析CSV文件以及其他缺少的元素。

P.p.s:您可以完全避免循环计数器i

for attr, val in zip(firstLine, line):
  setattr(self, attr, val)

P.p.s:这是一个完整的工作样本:

import csv

def classMaker(filename):
  class newClass(object):
    def __init__(self, line):
      for attr, val in zip(firstLine, line):
        setattr(self, attr, val)
  with open(filename, 'rb') as csvfile:
    spamreader = csv.reader(csvfile)
    firstLine = spamreader.next()
    return [newClass(line) for line in spamreader]

x = classMaker("/tmp/x.csv")
print x[0].Name