Johann Davel De Beer
Johann Davel De Beer

Reputation: 51

Python strange NameError for def

My code isnt too long so here is the whole program, when i run it it says

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

It seems too simple, whats happening here ? It worked just before i took extract and copied it and renamed it to xmlp, i then made a new button to execute it but then it broke, why does it say its not defined when it very clearly is ?

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()

Upvotes: 0

Views: 91

Answers (2)

Peter Badida
Peter Badida

Reputation: 12189

You have defined a function within a function:

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

which will exist only in the function's local scope.

Move the function outside of the function or (in case you really really want to use such solution) use global to define it in the global namespace:

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

Note that the function (hi()) that defines the inner function (hello()) needs to be called first in this case to execute global <name> so the function is stored into the global namespace instead of the local one.

Upvotes: 2

Ali Sajjad Rizavi
Ali Sajjad Rizavi

Reputation: 4490

There is indentation (spacing and tabs) problem here. Let's say you copied a function 'function2'. What you did is:

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

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

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

But the correct way is:

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

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

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

Upvotes: 2

Related Questions