非程序员 Python 3 教程/文件 I/O
这是一个简单的文件 I/O (输入/输出) 示例
# Write a file
with open("test.txt", "wt") as out_file:
out_file.write("This Text is going to out file\nLook at it and see!")
# Read a file
with open("test.txt", "rt") as in_file:
text = in_file.read()
print(text)
输出和文件 test.txt
的内容是
This Text is going to out file Look at it and see!
请注意,它在您运行程序的目录中写入了一个名为 test.txt
的文件。字符串中的 \n
告诉 Python 在它出现的地方插入一个换行符。
文件 I/O 的概述是
- 使用
open
函数获取文件对象 - 读写文件对象(取决于打开方式)
- 如果您没有使用
with
打开文件,您需要手动关闭它
第一步是获取文件对象。实现此目的的方法是使用 open
函数。格式为 file_object = open(filename, mode)
,其中 file_object
是要放置文件对象的变量,filename
是包含文件名(字符串),mode
是 "rt"
以读取文件为文本,或 "wt"
以写入文件为文本(以及其他一些我们将在此处跳过的内容)。接下来,可以调用文件对象函数。两个最常见的函数是 read
和 write
。write
函数将字符串添加到文件的末尾。read
函数读取文件中下一个内容,并将其作为字符串返回。如果没有给出参数,它将返回整个文件(如示例中所示)。
现在,我们之前制作的电话号码程序的新版本
def print_numbers(numbers):
print("Telephone Numbers:")
for k, v in numbers.items():
print("Name:", k, "\tNumber:", v)
print()
def add_number(numbers, name, number):
numbers[name] = number
def lookup_number(numbers, name):
if name in numbers:
return "The number is " + numbers[name]
else:
return name + " was not found"
def remove_number(numbers, name):
if name in numbers:
del numbers[name]
else:
print(name," was not found")
def load_numbers(numbers, filename):
in_file = open(filename, "rt")
while True:
in_line = in_file.readline()
if not in_line:
break
in_line = in_line[:-1]
name, number = in_line.split(",")
numbers[name] = number
in_file.close()
def save_numbers(numbers, filename):
out_file = open(filename, "wt")
for k, v in numbers.items():
out_file.write(k + "," + v + "\n")
out_file.close()
def print_menu():
print('1. Print Phone Numbers')
print('2. Add a Phone Number')
print('3. Remove a Phone Number')
print('4. Lookup a Phone Number')
print('5. Load numbers')
print('6. Save numbers')
print('7. Quit')
print()
phone_list = {}
menu_choice = 0
print_menu()
while True:
menu_choice = int(input("Type in a number (1-7): "))
if menu_choice == 1:
print_numbers(phone_list)
elif menu_choice == 2:
print("Add Name and Number")
name = input("Name: ")
phone = input("Number: ")
add_number(phone_list, name, phone)
elif menu_choice == 3:
print("Remove Name and Number")
name = input("Name: ")
remove_number(phone_list, name)
elif menu_choice == 4:
print("Lookup Number")
name = input("Name: ")
print(lookup_number(phone_list, name))
elif menu_choice == 5:
filename = input("Filename to load: ")
load_numbers(phone_list, filename)
elif menu_choice == 6:
filename = input("Filename to save: ")
save_numbers(phone_list, filename)
elif menu_choice == 7:
break
else:
print_menu()
print("Goodbye")
请注意,它现在包含文件保存和加载功能。以下是我的运行程序两次后的输出
1. Print Phone Numbers 2. Add a Phone Number 3. Remove a Phone Number 4. Lookup a Phone Number 5. Load numbers 6. Save numbers 7. Quit Type in a number (1-7): 2 Add Name and Number Name: Jill Number: 1234 Type in a number (1-7): 2 Add Name and Number Name: Fred Number: 4321 Type in a number (1-7): 1 Telephone Numbers: Name: Jill Number: 1234 Name: Fred Number: 4321 Type in a number (1-7): 6 Filename to save: numbers.txt Type in a number (1-7): 7 Goodbye
1. Print Phone Numbers 2. Add a Phone Number 3. Remove a Phone Number 4. Lookup a Phone Number 5. Load numbers 6. Save numbers 7. Quit Type in a number (1-7): 5 Filename to load: numbers.txt Type in a number (1-7): 1 Telephone Numbers: Name: Jill Number: 1234 Name: Fred Number: 4321 Type in a number (1-7): 7 Goodbye
该程序的新的部分是
def load_numbers(numbers, filename):
in_file = open(filename, "rt")
while True:
in_line = in_file.readline()
if not in_line:
break
in_line = in_line[:-1]
name, number = in_line.split(",")
numbers[name] = number
in_file.close()
def save_numbers(numbers, filename):
out_file = open(filename, "wt")
for k, v in numbers.items():
out_file.write(k + "," + v + "\n")
out_file.close()
首先,我们将查看程序的保存部分。首先,它使用命令 open(filename, "wt")
创建一个文件对象。接下来,它遍历并为每个电话号码创建一个行,使用命令 out_file.write(k + "," + v + "\n")
。这将写入包含姓名、逗号、号码和换行符的一行。
加载部分稍微复杂一些。它首先获取文件对象。然后,它使用 while True:
循环,一直循环直到遇到 break
语句。接下来,它使用 in_line = in_file.readline()
获取一行。readline
函数在到达文件末尾时将返回一个空字符串。if
语句检查这一点,并在发生这种情况时从 while
循环中 break
。当然,如果 readline
函数没有返回行尾的换行符,则无法判断空字符串是空行还是文件末尾,因此换行符保留在 readline
返回的内容中。因此,我们必须去掉换行符。行 in_line = in_line[:-1]
通过删除最后一个字符来实现这一点。接下来,行 name, number = in_line.split(",")
在逗号处将行拆分为名称和号码。然后将其添加到 numbers
字典中。
你可能会对自己说,“好吧,我知道如何读写文本文件,但如果我想打印文件而不打开另一个程序,怎么办?”
有几种不同的方法可以实现这一点。最简单的方法确实会打开另一个程序,但所有操作都在 Python 代码中处理,不需要用户指定要打印的文件。此方法涉及调用另一个程序的子进程。
还记得我们在上面程序中写入输出的文件吗?让我们使用该文件。请记住,为了防止一些错误,此程序使用了下一章中的概念。请随时在下一章之后重新访问此示例。
import subprocess
def main():
try:
print("This small program invokes the print function in the Notepad application")
#Lets print the file we created in the program above
subprocess.call(['notepad','/p','numbers.txt'])
except WindowsError:
print("The called subprocess does not exist, or cannot be called.")
main()
subprocess.call
接受三个参数。在本文档的示例中,第一个参数应该是您要从中调用打印子进程的程序名称。第二个参数应该是该程序中的特定子进程。为简单起见,只需了解在本文档中,'/p'
是用于通过指定应用程序访问打印机的子进程。最后一个参数应该是您要发送到打印子进程的文件名称。在本例中,它与本章前面使用的文件相同。
现在修改字典部分中的成绩程序,使其使用文件 I/O 来保存学生的记录。
现在修改字典部分中的成绩程序,使其使用文件 I/O 来保存学生的记录。
assignments = ['hw ch 1', 'hw ch 2', 'quiz ', 'hw ch 3', 'test']
students = { }
def load_grades(gradesfile):
inputfile = open(gradesfile, "r")
grades = [ ]
while True:
student_and_grade = inputfile.readline()
student_and_grade = student_and_grade[:-1]
if not student_and_grade:
break
else:
studentname, studentgrades = student_and_grade.split(",")
studentgrades = studentgrades.split(" ")
students[studentname] = studentgrades
inputfile.close()
print("Grades loaded.")
def save_grades(gradesfile):
outputfile = open(gradesfile, "w")
for k, v in students.items():
outputfile.write(k + ",")
for x in v:
outputfile.write(str(x) + " ")
outputfile.write("\n")
outputfile.close()
print("Grades saved.")
def print_menu():
print("1. Add student")
print("2. Remove student")
print("3. Load grades")
print("4. Record grade")
print("5. Print grades")
print("6. Save grades")
print("7. Print Menu")
print("9. Quit")
def print_all_grades():
if students:
keys = sorted(students.keys())
print('\t', end=' ')
for x in assignments:
print(x, '\t', end=' ')
print()
for x in keys:
print(x, '\t', end=' ')
grades = students[x]
print_grades(grades)
else:
print("There are no grades to print.")
def print_grades(grades):
for x in grades:
print(x, '\t', end=' ')
print()
print_menu()
menu_choice = 0
while menu_choice != 9:
print()
menu_choice = int(input("Menu Choice: "))
if menu_choice == 1:
name = input("Student to add: ")
students[name] = [0] * len(assignments)
elif menu_choice == 2:
name = input("Student to remove: ")
if name in students:
del students[name]
else:
print("Student:", name, "not found")
elif menu_choice == 3:
gradesfile = input("Load grades from which file? ")
load_grades(gradesfile)
elif menu_choice == 4:
print("Record Grade")
name = input("Student: ")
if name in students:
grades = students[name]
print("Type in the number of the grade to record")
print("Type a 0 (zero) to exit")
for i,x in enumerate(assignments):
print(i + 1, x, '\t', end=' ')
print()
print_grades(grades)
which = 1234
while which != -1:
which = int(input("Change which Grade: "))
which -= 1
if 0 <= which < len(grades):
grade = input("Grade: ") # Change from float(input()) to input() to avoid an error when saving
grades[which] = grade
elif which != -1:
print("Invalid Grade Number")
else:
print("Student not found")
elif menu_choice == 5:
print_all_grades()
elif menu_choice == 6:
gradesfile = input("Save grades to which file? ")
save_grades(gradesfile)
elif menu_choice != 9:
print_menu()