从另一个Python文件调用函数

2024-04-19 23:10:05 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我有点不知所措,因为除了捕获异常之外,我没有得到任何其他错误,有什么想法吗?我已经发布了下面的代码和评论

错误:分配前引用的局部变量“user\u 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",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正在导入的文件

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

Tags: textfromimportidnewplacerootwidth
2条回答

不可能知道您的问题是什么,因为代码中没有引用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块中的代码永远不会运行

Globals通常是一个坏主意,因为它们很容易出错,而且它们往往会掩盖代码真正在做什么。“永不说永不”,但我要说的是,我很少发现Python中需要全局变量。在您的情况下,我认为最好让Write.scan()返回新用户id的值,而不是将其作为全局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()

相关问题 更多 >