从 file/saving 数据读取元组列表到文件
Reading list of tuples from a file/saving data to a file
我有一个给定学生学期的 类 列表。我想将 类 的列表保存到名为 classes.txt 的 txt 文件中。这充当一种“保存”文件。再次打开时,程序将读取文件并知道 类 学生正在学习什么。
我用下面的代码这样做:
def write_out():
f_out = open('classes.txt', 'w')
# classes is a list of classes that the student has created
# all the classes are objects which have a few parameters listed below
for course in classes:
f_out.write(str(Course.course_name(course)) + ',' + str(Course.credits(course)) + ',' + str() + ',' + str(Course.assignments(course)) + '\n')
写入的文件内容如下:
Bio,4,[('exam', 100)],[]
calc,4,[('exam', 50)],[]
一个课程对象由几个参数定义:
- 一个名字(即'Bio')
- 学分数
- 课程评分类别的元组列表(类别名称,然后是权重)
- 作业列表*
*作业列表是 作业 对象的列表,这些对象由名称、类别和等级定义
我选择将类别保留为元组,因为它看起来更简单。
我的问题是在程序启动时尝试读取文件时出现的。虽然将分配和类别写入列表相对简单,但读回它变得更加困难,因为当我将元组列表转换回例如类别时似乎有双引号。
我的问题是:如何将 txt 文件中的元组和列表更轻松地读取到我的程序中?
我是从阅读这个 开始的,但我走到了死胡同,因为这个 post 更多的是关于将元组专门保存到一个文件中,而我有很多参数需要转换成启动程序时的对象。
我想扩展这个 post 以更多地了解一般的保存文件,以便更好地理解我应该如何解决这个问题。
读取文件后,我根据保存文件中的参数创建了一个新的 Course 对象,并将其添加到名为 'courses' 的列表中,以后可以访问该列表。
旁注:
我什至不确定这种方法是否是最有效的做事方式,所以如果有人对我如何更有效地将课程保存到文件有更好的想法,那么我 100% 愿意接受它。我计划将大量 类 和作业写入该文件,因此正确写入非常重要
感谢您的帮助,这是我在学习道路上很早就开始的一个项目,所以我只是想重新访问它以了解如何将数据保存到文件中:p
我将为您提供一个 DIY 解决方案,无需外部库,让您了解工作流程。评论中的建议比较好,但下划线原则应该“相似”。
此处不考虑性能、安全性,将其视为您学习路径的编码更新(或者我希望如此)。
要求:
- 写入文件时使用唯一的分隔符,当你在第二个瞬间阅读它时更容易。我选择
;
但可以自由更改它(,
与列表冲突,& co)
- 在写字符串对象“double double”时引用它们,这样在文件中它们将被双引号包围(
eval
需要,请参见下一步),因此字符串的形式应为 '"Bio"'
- 使用
eval
将字符串“复活”为对象
- 在课程 class 中添加 write/read 方法。特别地,reader 是一个 class 方法,因为它 returns 一个 class 实例
class Course:
SEP = ';' # should be a unique character(s)
def __init__(self, name, credits_, grading_cats, assignments):
self.name, self.credits, self.grading_cats, self.assignments = self.data = name, credits_, grading_cats, assignments
def __str__(self): # not needed but useful to understand the difference with "write_file_formatter", see 2.
return f'{self.SEP}'.join( str(i) for i in self.data)
def write_file_formatter(self):
return f'{self.SEP}'.join( f'"{i}"' if isinstance(i, str) else str(i) for i in self.data)
@classmethod
def read_file_formatter(cls, course_string):
return cls(*map(eval, course_string.split(cls.SEP)))
# the courses
c1 = Course('Bio', 4, [('exam', 100)], [])
c2 = Course('cal', 4, [('exam', 50)], [])
print(c1.write_file_formatter())
# "Bio";4;[('exam', 100)];[]
print(c2.write_file_formatter())
# "cal";4;[('exam', 50)];[]
# simulate text file
courses_from_file = c1.write_file_formatter() + '\n' + c2.write_file_formatter()
# "Bio";4;[('exam', 100)];[]
# "cal";4;[('exam', 50)];[]
# simulate read from file
for course in courses_from_file.split('\n'):
c = Course.read_file_formatter(course)
print(type(c), c)
# <class '__main__.Course'> Bio;4;[('exam', 100)];[]
# <class '__main__.Course'> cal;4;[('exam', 50)];[]
我有一个给定学生学期的 类 列表。我想将 类 的列表保存到名为 classes.txt 的 txt 文件中。这充当一种“保存”文件。再次打开时,程序将读取文件并知道 类 学生正在学习什么。
我用下面的代码这样做:
def write_out():
f_out = open('classes.txt', 'w')
# classes is a list of classes that the student has created
# all the classes are objects which have a few parameters listed below
for course in classes:
f_out.write(str(Course.course_name(course)) + ',' + str(Course.credits(course)) + ',' + str() + ',' + str(Course.assignments(course)) + '\n')
写入的文件内容如下:
Bio,4,[('exam', 100)],[]
calc,4,[('exam', 50)],[]
一个课程对象由几个参数定义:
- 一个名字(即'Bio')
- 学分数
- 课程评分类别的元组列表(类别名称,然后是权重)
- 作业列表*
*作业列表是 作业 对象的列表,这些对象由名称、类别和等级定义
我选择将类别保留为元组,因为它看起来更简单。
我的问题是在程序启动时尝试读取文件时出现的。虽然将分配和类别写入列表相对简单,但读回它变得更加困难,因为当我将元组列表转换回例如类别时似乎有双引号。
我的问题是:如何将 txt 文件中的元组和列表更轻松地读取到我的程序中?
我是从阅读这个
我想扩展这个 post 以更多地了解一般的保存文件,以便更好地理解我应该如何解决这个问题。
读取文件后,我根据保存文件中的参数创建了一个新的 Course 对象,并将其添加到名为 'courses' 的列表中,以后可以访问该列表。
旁注: 我什至不确定这种方法是否是最有效的做事方式,所以如果有人对我如何更有效地将课程保存到文件有更好的想法,那么我 100% 愿意接受它。我计划将大量 类 和作业写入该文件,因此正确写入非常重要
感谢您的帮助,这是我在学习道路上很早就开始的一个项目,所以我只是想重新访问它以了解如何将数据保存到文件中:p
我将为您提供一个 DIY 解决方案,无需外部库,让您了解工作流程。评论中的建议比较好,但下划线原则应该“相似”。
此处不考虑性能、安全性,将其视为您学习路径的编码更新(或者我希望如此)。
要求:
- 写入文件时使用唯一的分隔符,当你在第二个瞬间阅读它时更容易。我选择
;
但可以自由更改它(,
与列表冲突,& co) - 在写字符串对象“double double”时引用它们,这样在文件中它们将被双引号包围(
eval
需要,请参见下一步),因此字符串的形式应为'"Bio"'
- 使用
eval
将字符串“复活”为对象 - 在课程 class 中添加 write/read 方法。特别地,reader 是一个 class 方法,因为它 returns 一个 class 实例
class Course:
SEP = ';' # should be a unique character(s)
def __init__(self, name, credits_, grading_cats, assignments):
self.name, self.credits, self.grading_cats, self.assignments = self.data = name, credits_, grading_cats, assignments
def __str__(self): # not needed but useful to understand the difference with "write_file_formatter", see 2.
return f'{self.SEP}'.join( str(i) for i in self.data)
def write_file_formatter(self):
return f'{self.SEP}'.join( f'"{i}"' if isinstance(i, str) else str(i) for i in self.data)
@classmethod
def read_file_formatter(cls, course_string):
return cls(*map(eval, course_string.split(cls.SEP)))
# the courses
c1 = Course('Bio', 4, [('exam', 100)], [])
c2 = Course('cal', 4, [('exam', 50)], [])
print(c1.write_file_formatter())
# "Bio";4;[('exam', 100)];[]
print(c2.write_file_formatter())
# "cal";4;[('exam', 50)];[]
# simulate text file
courses_from_file = c1.write_file_formatter() + '\n' + c2.write_file_formatter()
# "Bio";4;[('exam', 100)];[]
# "cal";4;[('exam', 50)];[]
# simulate read from file
for course in courses_from_file.split('\n'):
c = Course.read_file_formatter(course)
print(type(c), c)
# <class '__main__.Course'> Bio;4;[('exam', 100)];[]
# <class '__main__.Course'> cal;4;[('exam', 50)];[]