简体   繁体   English

错误-UnboundLocalError:分配前已引用本地变量“ VARIABLE_NAME”

[英]Error - UnboundLocalError: local variable 'VARIABLE_NAME' referenced before assignment

I am running a piece of python code on a raspberry pi. 我在树莓派上运行一段python代码。
The function of the code is that GPIO 5 is set as a pull up resistor with a momentary switch attached. 该代码的功能是将GPIO 5设置为连接了瞬时开关的上拉电阻。 When the switch is pressed it grounds the pull up resistor. 按下开关时,它将上拉电阻器接地。 I am attempting to use the button push to trigger a callback. 我正在尝试使用按钮按下来触发回调。
The callback works like this: 回调的工作方式如下:
If the button is pressed and detected as still pressed it defines a variable called "t1" as the current time. 如果按下该按钮并且检测到该按钮仍处于按下状态,则它将定义一个称为“ t1”的变量作为当前时间。
If the button is detected as no longer pressed it defines a variable called "t2" then subtracts "t1" from "t2" to find the time difference (amount of time button was held down for). 如果检测到不再按下按钮,则它定义一个变量“ t2”,然后从“ t2”中减去“ t1”以找到时间差(按住按钮的时间)。 It then converts that value to an integer defined as variable "deltaseconds". 然后将其转换为定义为变量“ deltaseconds”的整数。 Then it takes action based on the length the button was held for. 然后,它会根据按钮保持的时间采取行动。 If more than 7 seconds, reboot the raspberry pi, if more than 1 second but less than 7 it toggles output GPIO(12) between high and low. 如果超过7秒,请重新启动树莓派,如果超过1秒但少于7秒,它将在高和低之间切换输出GPIO(12)。

The issue I am experiencing is like this: 我遇到的问题是这样的:
The code runs 代码运行
When the button is pressed I see the print of "Button 5 pressed" 当按下按钮时,我看到“按下按钮5”的打印
When the button is released I see the print "Button 5 released" 释放按钮后,我看到打印“按钮5已释放”
Then an error is display as "UnboundLocalError: local variable 't1' referenced before assignment" 然后错误显示为"UnboundLocalError: local variable 't1' referenced before assignment"
The error is in reference to line 21 delta = t2-t1 该错误是参考第21行的delta = t2-t1

The full code looks like this: 完整的代码如下所示:

import os
import RPi.GPIO as GPIO
import webiopi
import time
import datetime
from datetime import datetime
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
BUTTON_5 = 5
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(12,GPIO.OUT)
GPIO.output(12,1)
#Just to visually distinguish between setup steps and main program
def pressed(BUTTON_5):
    if GPIO.input(5) == False:
        t1 = datetime.now()
        print "Button 5 pressed"
    elif GPIO.input(5) == True:
        print "Button 5 released"
        t2 = datetime.now()
        delta = t2-t1
        deltaseconds = delta.total_seconds()
        if (deltaseconds > 7) : # pressed for > 7 seconds
            print "Restarting System"
            subprocess.call(['shutdown -r now "System halted by GPIO action" &'], shell=True)
        elif (deltaseconds > 1) : # press for > 1 < 7 seconds
            print "Toggling GPIO 12"
            GPIO.output(12, not GPIO.input(12))
GPIO.add_event_detect(BUTTON_5, GPIO.BOTH, bouncetime=200)
GPIO.add_event_callback(BUTTON_5, pressed)
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    GPIO.cleanup()       # clean up GPIO on CTRL+C exit

Check the scope of your variables. 检查变量的范围。 t1 is defined in the == False block. t1在== False块中定义。 Line 21 is in the elif block. 第21行在elif块中。 When a block ends, all local variables are destroyed (or at least inaccessible). 当块结束时,所有局部变量都将被销毁(或至少不可访问)。

To correct this, add a line to see if t1 is defined at the beginning of your loop, and if it is not defined, define it to something unreasonable (that you may decide to check against later). 要更正此问题,请添加一行以查看是否在循环的开头定义了t1,如果未定义,则将其定义为不合理的内容(您可以稍后决定进行检查)。

t1 should be defined outside pressed(BUTTON_5) . t1应该在pressed(BUTTON_5)之外定义。 You want to preserve the value from one call of this function to the next. 您要保留从此函数的一次调用到下一次调用的值。 While it is possible to possible to have static variables in a python function (by making them attributes of the function), it's generally clearer to make them global (in python 2). 尽管可以在python函数中具有静态变量(通过使它们成为函数的属性),但通常更清楚地将它们设置为全局变量(在python 2中)。 So, just put global t1 at the start of your function. 因此,只需将global t1放在函数的开头即可。

I should mention that global variables can quickly get out of hand, but if the variable is only being accessed in one function, there's no problem. 我应该提到全局变量可以很快失去控制,但是如果仅在一个函数中访问该变量,就没有问题。

After a substantial amount of investigating and learning I was able to achieve the desired result with the following code: 经过大量的研究和学习,我可以使用以下代码获得所需的结果:

import os
import RPi.GPIO as GPIO
import webiopi
import time  
import subprocess
import datetime
from datetime import datetime
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
BUTTON_5 = 5
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(12,GPIO.OUT)
GPIO.output(12,1)
#Just to visually distinguish between setup steps and main program
t1 = 999999999999999999999
def pressed(BUTTON_5):
    if GPIO.input(5) == False:
        global t1 
        t1 = datetime.now()
        print "Button 5 pressed"
    elif GPIO.input(5) == True:
        print "Button 5 released"
        t2 = datetime.now()
        delta = t2-t1
        deltaseconds = delta.total_seconds()
        if (deltaseconds > 7) : # pressed for > 7 seconds
            print "Restarting System"
            subprocess.call(['shutdown -r now "System halted by GPIO action" &'], shell=True)
        elif (deltaseconds > 1) : # press for > 1 < 7 seconds
            print "Toggling GPIO 12"
            GPIO.output(12, not GPIO.input(12))
GPIO.add_event_detect(BUTTON_5, GPIO.BOTH, bouncetime=200)
GPIO.add_event_callback(BUTTON_5, pressed)
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    GPIO.cleanup()       # clean up GPIO on CTRL+C exit  

This code seems to run smoothly and I have tested it thoroughly. 这段代码似乎运行顺利,我已经对其进行了彻底的测试。 I had to define "t1" as a global variable, once I learned what they were and how they work it all started to fall into place. 一旦我了解了它们是什么以及它们如何工作,就必须将“ t1”定义为一个全局变量,所有这些都开始出现。

Thank you to everyone who contributed to me getting to this answer. 感谢所有为我做出这一贡献的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UnboundLocalError:分配前已引用本地变量“名称” - UnboundLocalError: local variable 'name' referenced before assignment UnboundLocalError:赋值前引用的局部变量'error' - UnboundLocalError: local variable 'error' referenced before assignment UnboundLocalError: 赋值前引用的局部变量错误 - UnboundLocalError: local variable referenced before assignment error UnboundLocalError:分配前已引用本地变量“ Video_Name” - UnboundLocalError: local variable 'Video_Name' referenced before assignment 修复UnboundLocalError:在python中赋值之前引用的局部变量“名称” - Fixing UnboundLocalError: local variable 'name' referenced before assignment in python UnboundLocalError:赋值前引用了局部变量“name_chk” - UnboundLocalError: local variable 'name_chk' referenced before assignment UnboundLocalError:分配前引用的局部变量“dest_file_name” - UnboundLocalError: local variable 'dest_file_name' referenced before assignment UnboundLocalError:分配前已引用局部变量“ ticketCost” - UnboundLocalError: local variable 'ticketCost' referenced before assignment UnboundLocalError:赋值前引用了局部变量“df” - UnboundLocalError: local variable 'df' referenced before assignment UnboundLocalError:分配前已引用局部变量“ getBottles” - UnboundLocalError: local variable 'getBottles' referenced before assignment
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM