如何从.txt文件创建列表,然后将列表值转换为对象



我是Python的初学者,遇到了学校项目的麻烦。我正在尝试创建一个图书馆库存管理系统,基于一个名为books.txt的文件

首先,这里是books.txt的原始数据

Mastering Windows Server 2019 - Second Edition;Krause,Jordan;978-1789804539;005.4476/KRA;5;3;
Windows Server 2019 & PowerShell All In One For Dummies;Perrot,Sara;978-1119560715;005.4476/PER;10;2;
Windows Server Automation with PowerShell Cookbook - Fouth Edition;Lee,Thomas;978-1800568457;005.4476/LEE;3;1;
Python Cookbook: Recipes for Mastering Python 3;Beazley,David;978-1449340377;005.133/BEA;10;8;
Automate the Boring Stuff With Python;Sweigart,Al;978-1593275990;005.133/SWE;10;10;
Head First Python - 2nd Edition;Barry,Paul;978-1491919538;005.133/BAR;4;2;
Python Crash Course - 2nd Edition;Matthes,Eric;978-1593279288;005.133/MAT;12;8;
Python for Dummies;Maruch,Stef;978-0471778646;005.133/MAR;5;0;
Beginning Programming with Python for Dummies;Mueller,John Paul;978-1119457893;005.133/MUE;7;5;
Beginning COBOL for Programmers;Coughlan,Michael;978-1430262534;005.133/COU;1;0;

这里我要做的是将这些图书对象的列表存储在一个变量中。该程序的目的是修改图书对象列表,而不是直接修改.txt文件。完成所有这些之后,用户可以保存更改,然后覆盖.txt文件。无论如何,我已经尝试了许多不同的东西,现在我觉得这个函数在读取和分割文件中的行以创建列表方面最接近我。

#Apparently 'with open' stops you from having to close the file.
#Copy of display() for the purposes of playing around.
def inventory3():
print("nName t t Author t t ISBN t t Call Number t t Stock t t Loaned")
with open("books.txt", "r") as inventoryfile:
for line in inventoryfile:
strip_lines=line.strip()
inventory = strip_lines.split(";")
print(inventory)

这正确地显示了books.txt文件中的所有行(我不希望方括号显示,但这是稍后的问题),并且我从测试(像test = inventory[-3:]这样的东西)中知道它作为列表的功能是正确的。现在的目标是"索引"存储的列表。来创建图书对象,显然,我创建的每个图书对象都应该存储在单独的列表中。这是提供给我的示例。

books.append(Book(line[0],line[1],line[2],line[3],line[4],line[5]))

我之前创建了一个book类,像这样

class Book:
def __init__(self, title, author, isbn, callnumber, stock, loaned):
self.title = title
self.author = author
self.isbn = isbn
self.callnumber = callnumber
self.stock = stock
self.loaned = loaned
def getTitle(self):
return self.title
def getAuthor(self):
return self.author
def getISBN(self):
return self.isbn
def getCallNumber(self):
return self.callnumber
def getStock(self):
return self.stock
def getLoaned(self):
return self.loaned

我对如何将这两者联系在一起有点困惑。我没有看到从获得文本文件的内容显示到突然将它们全部转换为对象(然后可以单独删除,添加新书等)的进展。我花了几天时间在谷歌和youtube上搜索,但一无所获,所以我来这里寻求帮助。非常感谢。

你就快成功了!inventory是一个列表(因此使用方括号)。

要创建Book对象,只需更新给出的示例:

books.append(Book(inventory[0],inventory[1],inventory[2],inventory[3],inventory[4],inventory[5]))

要打印不带方括号的内容,请将print语句更新为:

print(' '.join(inventory))

似乎您想使用在inventory3中创建的列表来实例化您的Book类。在这种情况下,您可以尝试稍微改变一下函数并添加一个返回值,如下所示:

def inventory3():
inventory = []
print("nName t t Author t t ISBN t t Call Number t t Stock t t Loaned")
with open("books.txt", "r") as inventoryfile:
for line in inventoryfile:
strip_lines=line.strip()
inventory_line = strip_lines.split(";")[:-1] # Use-1 to get rid of all empty double quotes ('') in the end of each list
print(inventory_line)
inventory.append(inventory_line)
return inventory

你可以这样做:

inventory = inventory3()
books = []
for book_details in inventory:
books.append(Book(book_details[0],book_details[1], book_details[2],book_details[3],book_details[4],book_details[5]))
print(books)

你将看到你创建的对象。

并且,如果您确实不需要每个列表的And中空的",正如我建议的那样,您可以通过列表解包来完成,它将更加python化。这样的:

inventory = inventory3()
books = []
for book_details in inventory:
books.append(Book(*book_details))
print(books)

*book_details将与book_details[0],book_details[1], book_details[2],book_details[3],book_details[4],book_details[5]完全相同。

编辑

正如在注释中所说,我正在添加一个使用数据类的示例。

from dataclasses import dataclass
@dataclass
class Book:
title:str
author:str
isbn:str
callnumber:str
stock:str
loaned:str
# Your Functions
...

如果你使用一个数据类并打印你的对象,你会得到一些可以帮助你的东西:

Book(title='Mastering Windows Server 2019 - Second Edition', author='Krause,Jordan', isbn='978-1789804539', callnumber='005.4476/KRA', stock='5', loaned='3')

代替:

<__main__.Book object at 0x000001F1D23BFFA0>

如果你想要自己定义的东西,你可以实现你的book类的repr方法:

class Book:
def __init__(self, title, author, isbn, callnumber, stock, loaned):
self.title = title
self.author = author
self.isbn = isbn
self.callnumber = callnumber
self.stock = stock
self.loaned = loaned
def __repr__(self):
return self.title + '/' + self.author
# Your Functions
...

Emmacb上面的答案回答了你的问题。

只是为了补充,您可以在创建Book类时使用@dataclass装饰器。这将减少代码长度,并提高可读性。也没有必要定义Book.getXXX方法,因为这些方法可以通过属性名

直接访问。
from dataclasses import dataclass
@dataclass
class Book:
title: str
author: str
isbn: str
callnumber: str
stock : str
loaned : str

book_one = Book('Title', 'Author','ISBN', 'Call Number', 'Stock', 'loaned')
book_one_title = book_one.title
print(book_one_title)

这需要您指定数据的类型,在本例中我假设所有字符串。

最新更新