通过一个函数改变一个全局变量: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 data
将 data
从模块名称 space 包含到函数名称 space 中,以便函数中的所有嵌套环境可以访问它们(免责声明:这是对内部如何处理范围的过度简化)
希望对您有所帮助!
#!/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 data
将 data
从模块名称 space 包含到函数名称 space 中,以便函数中的所有嵌套环境可以访问它们(免责声明:这是对内部如何处理范围的过度简化)
希望对您有所帮助!