Python def 的奇怪 NameError

Python strange NameError for def

我的代码不太长,所以这是整个程序,当我 运行 它说

NameError: name 'xmlp' is not defined for line 88

好像太简单了,这是怎么回事? 它在我提取并复制它并将其重命名为 xmlp 之前起作用,然后我制作了一个新按钮来执行它但后来它坏了,为什么它说它没有定义而它非常清楚是什么?

from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import tkinter as tk

import xml.etree.ElementTree as ET

interface = tk.Tk()
interface.geometry("900x500")
interface.title("Text display")

T = tk.Text(interface, height=20, width=150)
T.grid(column=1, row=2, columnspan=3)

def openfile(): # open your file and load it into the text widget

    global filename
    filename = filedialog.askopenfilename()
    print(filename)
    file = open(filename)
    global txt
    txt = file.read()

    T.delete('1.0', END)
    T.insert(tk.END, txt)

    return txt

def extract(): # take the opened file and write it to a text file
    open('somefile.txt', 'w').close()

    root = ET.fromstring(txt)

    str_params = root.findall('.//parameter/[parameterid="str"]')
    for param in str_params:
        if param.find('./name').text == 'Text':
            print(format(param.find('./value').text))
            with open('somefile.txt', 'a') as the_file:
                the_file.write(format(param.find('./value').text))
                the_file.write("\n")

    exportFileDir = open('somefile.txt',)

    txtExport = exportFileDir.read()

    T.delete('1.0', END)
    T.insert(tk.END,txtExport)

    def xmlp():  # take the opened file and write it to a text file
        open('somefile.txt', 'w').close()

        root = ET.fromstring(txt)

        str_params = root.findall('.//parameter/[parameterid="str"]')
        for param in str_params:
            if param.find('./name').text == 'Text2':
                print(format(param.find('./value').text))
                with open('somefile.txt', 'a') as the_file:
                    the_file.write(format(param.find('./value').text))
                    the_file.write("\n")

        exportFileDir = open('somefile.txt', )

        txtExport = exportFileDir.read()

        T.delete('1.0', END)
        T.insert(tk.END, txtExport)



def file_save():
    f = filedialog.asksaveasfile(mode='w', defaultextension=".txt")
    if f is None: # asksaveasfile return `None` if dialog closed with "cancel".
        return
    exportFileDir = open('somefile.txt')

    txtExport = exportFileDir.read()

    f.write(txtExport)
    f.close() # `()` was missing.

button = ttk.Button(interface, text="Open text File", command=openfile)  # <------
button.grid(column=1, row=3, sticky = W)

buttonex = ttk.Button(interface, text="Extract subtitles", command=extract)  # <------
buttonex.grid(column=2, row=3, sticky = W)

buttonexp = ttk.Button(interface, text="X XML P", command=xmlp)  # <------
buttonexp.grid(column=2, row=4, sticky = W)

buttonsv = ttk.Button(interface, text="Save as", command=file_save)  # <------
buttonsv.grid(column=3, row=3, sticky = W)

interface.mainloop()

此处存在 缩进(间距和制表符) 问题。 假设您复制了一个函数 'function2'。你所做的是:

def function1():
    print('hello 1')

    def function2():
        print('hello 2')

def function3():
    print('hello 3')

但正确的做法是:

def function1():
    print('hello 1')

def function2():
    print('hello 2')

def function3():
    print('hello 3')

您在一个函数中定义了一个函数:

def hi():
    def hello():
        print("Hello")
    hello()
    print("Hi")
hello()  # <- Error

它将仅存在于函数的本地范围内。

将函数移出函数或者(如果你真的想使用这样的解决方案)使用global在全局命名空间中定义它:

def hi():
    global hello
    def hello():
        print("Hello")
    hello()
    print("Hi")
hello()  # <- No error, after hi()

注意定义内部函数(hello())的函数(hi())在这种情况下需要先调用才能执行global <name> 所以函数存储在 global 命名空间而不是 local 命名空间中。