2015-05-04 51 views
0

我一直在尝试创建一个类,它将接受一个CSV文件,读取它并使用其中一行作为关键字将其排序到字典中。我可以在网上找到与csv文件有关的所有内容,并在课堂之外处理它们。将CSV排序到类中的字典

我试图打开csv文件(称为books.csv)并将每行读入Shelf类的私有属性,称为__books,它是一个字典。字典应该使用ISBN作为关键字。

我想将csv文件books.csv放到字典__books{ }中,并将第4行作为关键字,但每次运行它时,都会指出books.csv文件未被读入字典中。

的第一段代码是:

class Book: 

    def __init__(self, title, author, price, isbn): 
     self.title = title 
     self.author = author 
     self.price = price 
     self.isbn=isbn 

    def getISBN(self): 
     return self.isbn 


class Shelf: 

    __books={} 

    def __init__(self,filename): 
     f=open(filename, encoding="utf8") 
     csvreader = csv.reader(f) 

    for row in csvreader: 
     abook=Book(row[0],row[1],row[2],row[3]) 
     self.__books[row[4]]=abook 

这个代码将被调用到另一个文件和相应的代码是:

aShelf=Shelf("books.csv") 
    abook=aShelf._Shelf__books["0743482836"] 
    if abook.author == "A. Goose": 
     pass 
    else: 
     raise Exception 
+0

你是什么意思通过导入字典?你现在有什么不能正常工作? –

+0

很抱歉,如果不清楚。实际的问题是:打开csv文件(称为“books.csv”)并将每行读入Shelf类的一个私有属性,称为 __books,它是一个字典。字典应该使用ISBN作为关键字。我想将csv文件“books.csv”放入字典__books {}中,并将第四个拖放作为关键字,但每次运行它时,都会声明“books.csv”文件未被读入字典。 – Albi

+0

我认为它是由于在csvreader中开始行的缩进而引起的。如果你在一个层次上转换它,那么它将成为你的'__init__'方法的一部分,并且应该可以工作。 –

回答

0

我相信你的错误是,认为插入到部分字典不会正确缩进,因此在您调用__init__方法时不会运行

之前

def __init__(self,filename): 
    f=open(filename, encoding="utf8") 
    csvreader = csv.reader(f) 

for row in csvreader: 
    abook=Book(row[0],row[1],row[2],row[3]) 
    self.__books[row[4]]=abook 

def __init__(self,filename): 
    f=open(filename, encoding="utf8") 
    csvreader = csv.reader(f) 

    ''' indented here ''' 
    for row in csvreader: 
     abook=Book(row[0],row[1],row[2],row[3]) 
     self.__books[row[4]]=abook 

后,您还可以通过拆包值作为tuple消除你的循环丑陋指数语法。

注意:本节基于OP中更新的注释中的信息,与csv数据中的哪些索引有关,表示哪些书籍参数。前面的部分不会更新。

for _, title, author, price, isbn, *_ in csvreader: 
    self.__books[isbn] = Book(title, author, price, isbn) 

这应该更具可读性。唯一不清楚的是哪个索引是isbn,但我会让你找出一个。

1

代码有几个问题。首先,我认为__books应该被定义为一个实例变量,而不是一个类变量。你的方式,如果你创建Shelf多个实例,他们将分享字典(我不认为这是意图)。

其次,在阅读文件时,应该使用with语句,以免泄漏资源。第三,正如一些评论所建议的那样,你应该把想要用作键的列号作为参数。

最后,您可以提供__getitem__以便在查找书籍时允许更简单的语法。

class Shelf: 
    def __init__(self,filename, key_no=3): 
     self._books={} 
     with open(filename, encoding="utf8") as f: 
      csvreader = csv.reader(f) 
      for row in csvreader: 
       abook = Book(*[x.strip() for x in row]) 
       self._books[row[key_no].strip()] = abook 

    def __getitem__(self, isbn): 
     return self._books[isbn] 


aShelf=Shelf("books.csv") 
print(aShelf._books) 

abook = aShelf["0743482836"] 
if abook.author == "A. Goose": 
    pass 
else: 
    raise Exception 
+0

我从来不知道这意味着我的一个类变量+1。 –