1

所以,这是我的代码。

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 文件,并从字段名称中自动生成对象名称。

先感谢您。

4

2 回答 2

3

如果你使用,你可以避免newClass一起使用collections.namedtuple

CSVRow = namedtuple("CSVRow", firstLine)
return [CSVRow(*line) for line in csv]

这假定 CSV 标头将是有效的 Python 标识符(也就是说,如果您有像 "Some Value" 这样的整体,如果您不处理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模块以简化 CSV 处理。

于 2013-07-24T18:33:30.077 回答
2

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

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

有了这个:

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

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

例如:

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

data = classMaker('file.csv') 

将产生:

data[0].Name == 'Joe'

Ps 我假设您将添加文件 I/O、解析 CSV 文件和其他缺少的元素。

Pps:您可以完全避免循环计数器i

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

Pps:这是一个完整的工作示例:

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
于 2013-07-24T18:04:36.723 回答