简体   繁体   中英

Calling function from another Python file

I am trying to call a function from another Python file after a button is click. I have imported the file and used the FileName.fuctionName() to run the function. The problem is my exception keeps catching. I am guessing that the data from the function being called is not being grabbed.What I am trying to do is have a user fill out a Tkinter gui then click a button. Once the button is click the user will then be asked to scan their tag (rfid) and that data will then be sent to a firebase real time database which will store the user's inputted info along with the card_id and user_id that was created when the tag was scanned.

Im kinda at a loss because other than the exception catching I am not getting any other errors, any thoughts? I have posted the code below along with comments.

error : local variable 'user_id' referenced before assignment

from tkinter import *
#Second File
import Write
from tkcalendar import DateEntry
from firebase import firebase

data = {}

global user_id

# Firebase 
firebase= firebase.FirebaseApplication("https://xxxxxxx.firebaseio.com/",None)

# button click
def sub ():
    global user_id

    #setting Variables from user input
    name = entry_1.get()
    last = entry_2.get()
    number = phone.get()
 
    try:
        #Calling Function from other file
        Write.scan()
        if Write.scan():
            #getting the New User Id
            user_id= new_id

        
            #User Info being sent to the Database 
            data = {
            'Name #': name,
            'Last': last,
            'Number': number,
            'Card #':user_id
            }
        results = firebase.post('xxxxxxxx/User',data)
               
    except Exception as e:
        print(e)    

# setting main frame
root = Tk()
root.geometry('850x750')
root.title("Registration Form")

label_0 = Label(root, text="Registration form",width=20,font=("bold", 20))
label_0.place(x=280,y=10)

label_1 = Label(root, text="First Name",width=20,font=("bold", 10))
label_1.place(x=80,y=65)

entry_1 = Entry(root)
entry_1.place(x=240,y=65)

label_2 = Label(root, text="Last Name",width=20,font=("bold", 10))
label_2.place(x=68,y=95)

entry_2 = Entry(root)
entry_2.place(x=240,y=95)

phoneLabel = Label(root, text="Contact Number : ",width=20,font=("bold", 10))
phoneLabel.place(x=400,y=65)

phone = Entry(root)
phone.place(x=550,y=65)

Button(root, text='Submit',command = sub,width=20,bg='brown',fg='white').place(x=180,y=600)

root.mainloop()

Write.py file being Imported

import string
from random import*
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()

#Function being called
def scan():
    try:
        #Creating user hash
        c = string.digits + string.ascii_letters
        new_id = "".join(choice(c) for x in range(randint(25,25)))
        print("Please Scan tag")
    
        #Writing to tag
        reader.write(new_id)
        if reader.write(new_id):
            print("Tag Scanned")
        
        else:
            print("Scan Tag First")
        print("Scanning Complete")
    
    finally:
        GPIO.cleanup()

It's impossible to tell what your problem is, because there is no place in your code that references user_id and hence the error message you cite can't come from the code you provide. However, I see a pretty common mistake that your code appears to be making that could very well account for why you expect user_id to be defined somewhere in your code and yet it is not...

In your first block of code, the global user_id is not being set by the sub function. Rather, when the sub function calls user_id=new_id , it is creating and setting a variable that is local to that function. When that function ends, the result of that call is lost and the global user_id is still undefined.

What you want is to define user_id as being global inside of the sub() function. Just add global user_id anywhere near the top of the function definition.

Here's an example of what I'm talking about:

global x

def sub():
    x = 3
    
sub()
print(x)

result:

Traceback (most recent call last):
  File "t", line 7, in <module>
    print(x)
NameError: global name 'x' is not defined

whereas:

global x

def sub():
    global x
    x = 3
    
sub()
print(x)

result:

3

I see that the value new_id in one file isn't going to influence the value with the same name in the other file, for a similar reason as for the first problem. In both places it appears, new_id is a local variable that only exists in the enclosing function.

Another issue I see is that you're calling Write.scan() twice in a row. Do you mean to be calling it twice? I expect not.

Also, you're testing the return value of Write.scan() , but that function doesn't return a value. So I think that the code in the if block in the first file will never run.

Globals are a bad idea in general, as they're easy to get wrong and they tend to obscure what the code is really doing. "Never say never", but I'll say that I very rarely find the need for a global variable in Python. In your case, I think it would be much better to have Write.scan() return the value of the new user id instead of passing it back as a global. Since you're testing the value of Write.scan() , maybe this is what you were thinking of doing already. Here are the changes I'd make to address these three issues and hopefully get your code working the way you want...

...

def sub ():
    
    ...
    
    try:
        #Calling Function from other file
        new_id = Write.scan()
        if new_id:
            #getting the New User Id
            user_id= new_id
    
    ...

...

def scan():
    try:
        
        ...
        
        new_id = "".join(choice(c) for x in range(randint(25,25)))
        
        ...

        return new_id

    finally:
        GPIO.cleanup()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM