关闭 Python 中的文件

Closing a File in Python

我正在 Python 在 Spyder 上使用 Tkinter 编写代码。您可以在下面看到我的一种方法。不想放我的完整代码,因为它很长。我需要打开一个文件来读取一些信息。我的代码没有问题,它实际上工作得很好(做我想做的事)但是我不知道如何在完成后关闭我的文件。无论我把 'myFile.close()' 命令放在哪里,它都会给我另一种类型的错误。我想了解我应该把它放在哪里。由于 for 和 if,我对把它放在哪里有点困惑。你能帮帮我吗?

*** 已编辑 *** 使用下面的 myFile1.close() 命令,它会给出“ValueError:I/O 对已关闭文件的操作”。错误。

    def login(self):
        id_val = self.entry_1.get()
        pass_val = self.entry_2.get()
        myFile1 = open("ids.txt", "r")
        for line in myFile1:
            if line.find(id_val) == 0:
                self.pid,password,name,gender,age,phone=line.split(",")
                if password == pass_val:
                    box = Text(width=45, height=40)
                    box.place(x=1120, y=80)
                    self.first,self.last=name.split()
                    box.insert(END, "\n\n\tAd: ")
                    box.insert(INSERT, self.first)
                    box.insert(END, "\n\n\tSoyad: ")
                    box.insert(INSERT, self.last)        
                    box.insert(END, "\n\n\tCinsiyet: ")
                    box.insert(INSERT, gender)
                    box.insert(END, "\n\n\tYaş: ")
                    box.insert(INSERT, age)
                    box.insert(END, "\n\n\tTelefon: ")
                    box.insert(INSERT, phone)
                    self.patient_screen()
                    myFile1.close()
                else:
                    messagebox.showerror("Warning", "Wrong ID or password.")
                    myFile1.close()
                    break
            else:
                messagebox.showerror("Warning", "Wrong ID or password.")
                myFile1.close()
                break

我不熟悉 Spyder 或 Tkinter,但我建议对文件使用 context managers,它确保资源在上下文管理器之后关闭。

def login(self):
        id_val = self.entry_1.get()
        pass_val = self.entry_2.get()
        # myFile1 = open("ids.txt", "r")
        with open("ids.txt", "r") as myFile1 :
            for line in myFile1:
                if line.find(id_val) == 0:
                    self.pid,password,name,gender,age,phone=line.split(",")
                    if password == pass_val:
                        box = Text(width=45, height=40)
                        box.place(x=1120, y=80)
                        self.first,self.last=name.split()
                        box.insert(END, "\n\n\tAd: ")
                        box.insert(INSERT, self.first)
                        box.insert(END, "\n\n\tSoyad: ")
                        box.insert(INSERT, self.last)        
                        box.insert(END, "\n\n\tCinsiyet: ")
                        box.insert(INSERT, gender)
                        box.insert(END, "\n\n\tYaş: ")
                        box.insert(INSERT, age)
                        box.insert(END, "\n\n\tTelefon: ")
                        box.insert(INSERT, phone)
                        self.patient_screen()
                    else:
                        messagebox.showerror("Warning", "Wrong ID or password.")
                        break
                else:
                    messagebox.showerror("Warning", "Wrong ID or password.")
                    break

这是打开和关闭文件的正确但糟糕的方法:

f = open(filename,...)
# do something with f
f.close()

可以,但是有问题。如果中间要return,或者break,或者出现异常怎么办?那么你必须这样做:

f = open(filename, ...)
# do something with f
if condition:
    f.close()
    return something
# do something else with f
try:
    # do something which may fail
except:
    f.close()
    raise
if another condition:
    f.close()
    return something_else
# do more  with f
f.close()

这很快就会变得丑陋。为了避免这种情况,最好使用上下文管理器协议使用 with 关键字打开文件,因为这些文件会自动关闭。

同样复杂的例子:

with open(filename, ...) as f:
    # do something with f
    if condition:
        return something
    # do something else with f
    # do something which may fail
    if another condition:
        return something_else
    # do more  with f

# here, the file is closed automatically

基于 Caleb 的回答:为了提高可读性,我强烈建议通过先检查错误来扁平化代码,这样您就可以快速跳出循环,然后以相同的缩进级别继续,因为您知道自己不再处于错误状态。例如:

def login(self):
    id_val = self.entry_1.get()
    pass_val = self.entry_2.get()
    with open("ids.txt", "r") as myFile1 :
        for line in myFile1:
            if line.find(id_val) != 0:
                messagebox.showerror("Warning", "Wrong ID or password.")
                break

            # If you've reached this line, you know the ID is correct.
            self.pid,password,name,gender,age,phone=line.split(",")
            if password != pass_val:
                messagebox.showerror("Warning", "Wrong ID or password.")
                break

            # If you've reached this line, you know the password is correct.
            box = Text(width=45, height=40)
            box.place(x=1120, y=80)
            self.first,self.last=name.split()
            box.insert(END, "\n\n\tAd: ")
            box.insert(INSERT, self.first)
            box.insert(END, "\n\n\tSoyad: ")
            box.insert(INSERT, self.last)        
            box.insert(END, "\n\n\tCinsiyet: ")
            box.insert(INSERT, gender)
            box.insert(END, "\n\n\tYaş: ")
            box.insert(INSERT, age)
            box.insert(END, "\n\n\tTelefon: ")
            box.insert(INSERT, phone)
            self.patient_screen()

当你没有一大堆嵌套的 if 语句时,它的可读性要高得多。