从另一个Python文件调用函数

问题描述

单击按钮后,我试图从另一个Python文件调用函数。我已经导入了文件,并使用FileName.fuctionName()运行该函数。问题是我的异常一直在流行。我猜想被调用函数中的数据没有被抓取。我想做的是让用户填写Tkinter gui然后单击一个按钮。单击按钮后,将要求用户扫描其标签(rfid),然后将数据发送到Firebase实时数据库,该数据库将存储用户输入的信息以及在标签时创建的card_id和user_id已被扫描。

我有点茫然,因为除了捕获异常之外,我没有收到任何其他错误,有什么想法吗?我已经在下面发布了代码以及评论

错误 分配前已引用本地变量'user_id'

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",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",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 : ",10))
phoneLabel.place(x=400,y=65)

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

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

root.mainloop()

Write.py 文件已导入

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

解决方法

我们无法确定问题所在,因为代码中没有引用user_id的位置,因此您引用的错误消息不能来自您提供的代码。但是,我看到一个很常见的错误,即您的代码似乎正在犯错,这很可能可以解释为什么您希望在代码中的某个位置定义user_id,但事实并非如此……

在您的第一段代码中,user_id函数未设置全局sub。相反,当sub函数调用user_id=new_id时,它正在创建和设置该函数本地的变量。该函数结束后,该调用的结果将丢失,并且全局user_id仍未定义。

您想要的是将user_id定义为sub()函数内部的全局变量。只需在函数定义顶部附近的任意位置添加global user_id

这是我所谈论的例子:

global x

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

结果:

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

而:

global x

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

结果:

3
,

我看到一个文件中的值new_id不会影响另一个文件中具有相同名称的值,其原因与第一个问题类似。在这两个地方都显示new_id是一个局部变量,仅存在于封闭函数中。

我看到的另一个问题是您连续两次调用Write.scan()。您是说要两次打电话吗?我希望不会。

此外,您正在测试Write.scan()的返回值,但是该函数没有返回值。因此,我认为第一个文件的if块中的代码将永远不会运行。

总体而言,全局变量不是一个好主意,因为它们很容易出错,并且往往使代码的实际作用难以理解。 “永不言败”,但我会说我很少发现在Python中需要全局变量。对于您的情况,我认为让Write.scan()返回新用户ID的值而不是将其作为全局值传回会更好。由于您正在测试Write.scan()的值,因此也许这就是您正在考虑的。这是我为解决这三个问题而进行的更改,希望可以使您的代码按您想要的方式工作...

...

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