通过函数更改全局变量:UnboundLocalError

时间:2018-11-06 10:14:14

标签: python python-2.7 ubuntu-16.04

#!/usr/bin/python

import rospy
import serial
import time
from std_msgs.msg import String

ser = serial.Serial('/dev/ttyUSB0', 9600)
print (ser.name)
time.sleep(2)

#===========================================================
# An o y ine i kateuthynsi kinisis (mikos deksamenis)
# Gia kinisi se eutheia
x_d = 0 # mm
y_d = 2000
thita_d = 0 # moires i rads
#===========================================================

camera = [0, 0, 0]
error = [0, 0, 0]
data = [0, 0, 0]
print(data)
def camera_feedback():
    # dedomena apo camera-RPi-seiriaka apo allon komvo mallon...
    #camera = [x_c, y_c, thita_c]
    #x_c = camera[0]                    #isws mpei kwdikas gia na diavazei apo tin
    camera[0] = 0
    #y_c = camera[1]                    #seiriaki tu RPi (opws to serial_connection())
    camera[1] = camera[1] + 250
    #thita_c = camera[2]    
    camera[2] = 0
    print(camera)

def error_calculation():
    error[0] = x_d - camera[0]
    error[1] = y_d - camera[1]
    error[2] = thita_d - camera[2]
    print(error)

def controller_equations():
    # edw mpenun oi eksiswseis tu michali
    # kapws pernei to error kai alla dedomena kai dinei w, A, thita_mesi gia na stalun ston PIC
    if error != [0, 0, 0]:
        print(error)
        print(data)
        data[0] = 8
        data[1] = 8
        data[2] = 0
    else:
        data = [0, 0, 0]
    print('kokos')
    #data = [w, A, thita_mesi]     #na dw ti format dexete o kwdikas tu PIC

def serial_connection():
    rospy.init_node('serial_connection', anonymous = True)
    rate = rospy.Rate(10) #isws na min xreiazetai

    if not rospy.is_shutdown():

        ##data1 = bytearray(data)
        ##rdata = bytearray()
        ##rdata.extend(data1[0:2])
        ##rdata.extend(data1[2:5])
        ##vect = list(rdata)
        ##print(vect)

        if ser.isOpen():
            print ("Port Open")
            for i in range(1):
                #ser.write(b'5')
                #ser.write(chr(5)) auto stelnei kwdikopoiimenus xaraktires, ox$
                #ser.write(5)
                ser.write(bytes(data) + '\n')
                #print ('Hola!')
                #ser.write("Hola!\n")
                time.sleep(1)
                rate.sleep()

if __name__ == '__main__':
    try:
        while not rospy.is_shutdown():
            camera_feedback()
            error_calculation()
            controller_equations()
            serial_connection()
        ser.close()
    except rospy.ROSInterruptException:
        pass

我运行上面的代码,但出现错误: UnboundLocalError:分配前已引用本地变量“数据”

我想通过controller_equations()函数更改全局变量数据的值。我对函数camera_feedback()中的可变摄像机做了同样的操作,没有任何错误。我在其他帖子中搜索了答案,但是所有人都说不可能通过函数来​​碰到全局变量。任何可能的解决方案或技巧将不胜感激。我是Python的新手,我使用Ubuntu 16.04和Python 2.7。

先谢谢了。

1 个答案:

答案 0 :(得分:2)

正如重复的帖子回复所指出的那样,您需要使用globals来解决此问题

不过,请解释一下为什么它可以在camera_feedback而不是controller_equations中使用

您不需要globals语句即可直接在函数上下文中访问全局变量!!。但是,不建议保存您的生命周期,这样的调试问题

要解析变量,解释器始终在本地名称空间中查找变量(精确标记)的引用,然后再搜索全局(直接父级)名称空间

camera_feedback中,解释器在评估camera时会在本地名称空间中查找变量camera[0] = 0。 由于找不到,它将查找其直接父级(即module)名称空间

controller_equations中,您通过if..else语句在函数上下文中创建了新的环境上下文。由于在本地名称空间(data中找不到变量if..else context,因此会在直接父级(即函数上下文中,它也没有引用data)中查找变量,因此抛出{{1 }}错误

要解决此问题,您需要通过语句UnboundLocalErrordata从模块名称空间包括到函数名称空间,以便函数中的所有嵌套环境都可以访问它们(免责声明:内部人员如何处理作用域)

希望这会有所帮助!