通过一个函数改变一个全局变量:UnboundLocalError

Change a global variable through a function: UnboundLocalError

#!/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:赋值前引用的局部变量'data'

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

提前致谢。

正如重复的post回复所指出的,您需要使用globals来解决这个问题

但是,要解释为什么它在 camera_feedback 中有效但在 controller_equations

中无效

您不需要 globals 语句直接在函数上下文中访问全局变量!! 但是 不建议 以节省您调试此类问题的时间

为了解析一个变量,解释器在全局(直接父)名称space

中搜索之前总是在局部名称space中查找变量(准确地说是标签)引用

camera_feedback 中,解释器在计算 camera[0] = 0 时在局部名称 space 中查找变量 camera。 由于未找到,它会在其直接父级(即模块)中查找 namespace

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

要解决此问题,您需要通过语句 globals datadata 从模块名称 space 包含到函数名称 space 中,以便函数中的所有嵌套环境可以访问它们(免责声明:这是对内部如何处理范围的过度简化)

希望对您有所帮助!