变量文件名不存在时不存在

variable filename does not exist when it does

出于某种原因,我无法让我的代码工作 — 它向我显示变量不存在的错误。

这是我的代码:

from tkinter import *
from tkinter import messagebox as msg
from tkinter import filedialog #https://pythonspot.com/tk-file-dialogs/
def save():
    global filename
    try: #here, if variable `filename' does not exist, we will ask for a filename. if it does exist, we'll use it. kind of like how a normal text editor makes you save as the same file until you click "New".
        yolo = filename
        del yolo
        keepTheFilename = True
    except:
        keepTheFilename = False
    from os.path import expanduser
    home = expanduser("~")
    if keepTheFilename is True:
        filename = filedialog.asksaveasfilename(initialdir=home, title="Saving file")
    #print("Saving to  %s" % filename, end="\r")
    theText = text.get(0.0, "end-1c") #
    with open(filename, "w") as theFile:
        theFile.write(theText)
        print("Saving to  %s, done." % filename)
    slate.title(filename)
def openFile():
    from os.path import expanduser
    home = expanduser("~")
    filename = filedialog.askopenfilename(initialdir=home, title="Select file to open")
    with open(filename, "r") as theFile:
        theText = theFile.read()
        text.delete(0.0, END)
        text.insert(END, theText)
    slate.title(filename)
def deleteAll():
    text.delete(0.0, END)
    slate.title("slate")
    del filename
def hello():
    msg.showinfo("About", "slate is a decent plain-text editor. Thanks for using!")
    Label(slate, text="To-Dos: - add \"staying on file\" (instead of having to type the filename over and over again; - copy-paste functions; - and more!").pack()

slate = Tk() #set up window. `slate' is now the name of the window, internally
slate.title("slate") #set up window. `slate' is now the word in the title bar
scrollbar = Scrollbar(slate, orient=VERTICAL) #set up scrollbar
scrollbar.pack( side = RIGHT, fill = Y ) #vertical

text = Text(slate, yscrollcommand=scrollbar.set)
text.pack()
scrollbar.config( command = text.yview )
w = Button(slate, text="Save", command=save)
w2 = Button(slate, text="Open", command=openFile)

w.pack(padx=5, pady=10, side=LEFT)
w2.pack(padx=5, pady=10, side=LEFT)

mainloop()

这是我 运行 save()(通过单击保存按钮)时的错误:

File "slateGUI.py", line 17, in save
    with open(filename, "w") as theFile:
UnboundLocalError: local variable 'filename' referenced before assignment

如果我添加 global filename:

File "slateGUI.py", line 19, in save
    print("Saving to  %s" % filename, end="\r")
NameError: name 'filename' is not defined

有谁知道我该如何解决这个问题?谢谢!

如果出现异常,keepTheFilename = False。如果 keepTheFilename = Falseif 语句将不会启动,因此不会定义文件名。

def save():
    try: # If the exception occurs, keepTheFilename = False
        yolo = filename
        del yolo
        keepTheFilename = True
    except:
        keepTheFilename = False
    from os.path import expanduser
    home = expanduser("~")
    if keepTheFilename is True: # If the exception occurred, this if statement will not be launched, hence filename haven't been defined
        filename = filedialog.asksaveasfilename(initialdir=home, title="Saving file")
    print("Saving to  %s" % filename, end="\r")
    theText = text.get(0.0, "end-1c") #
    with open(filename, "w") as theFile:
        theFile.write(theText)
        print("Saving to  %s, done." % filename)
    slate.title(filename)

所以,感谢@AnnZen 的出色回答,我想通了:

def save():
    try: # If the exception occurs, keepTheFilename = False
        yolo = filename
        del yolo
        keepTheFilename = True
    except:
        keepTheFilename = False
    from os.path import expanduser
    home = expanduser("~")
    if keepTheFilename is not True: # If the exception occurred, this if statement will not be launched, hence filename haven't been defined
        filename = filedialog.asksaveasfilename(initialdir=home, title="Saving file")
    else:
        global filename
    print("Saving to  %s" % filename, end="\r")
    theText = text.get(0.0, "end-1c") #
    with open(filename, "w") as theFile:
        theFile.write(theText)
        print("Saving to  %s, done." % filename)
    slate.title(filename)

逻辑:如果keepTheFilename没有定义,它会询问路径。但是,如果已定义,它将保存到原始路径(在 else 块中使用 global filename)。

存在语法警告(来自 global filename):

slateGUI.py:16: SyntaxWarning: name 'filename' is assigned to before global declaration
  global filename

非常感谢 AnnZen!