Измените глобальную переменную с помощью функции: UnboundLocalError [duplicate]

#!/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Ƌ')
                #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.

Заранее спасибо.

Всего 1 ответ


Как уже указывалось дублирующимся ответом, вам нужно использовать globals для решения этой проблемы

Однако, чтобы объяснить, почему он работал в camera_feedback но не в controller_equations

Вам не нужна инструкция globals для доступа к глобальным переменным непосредственно в контексте функции !!. Однако не рекомендуется экономить время жизни от такой проблемы отладки

Чтобы разрешить переменную, интерпретатор всегда смотрит в локальное пространство имен для ссылки на переменную (точную метку) перед поиском в глобальном (непосредственном родительском) пространстве имен

В camera_feedback интерпретатор просматривает локальное пространство имен для переменной camera , когда он оценивает camera[0] = 0 . Поскольку он не найден, он смотрит в свое непосредственное родительское (т.е. модульное) пространство имен

В controller_equations вы создали новый контекст среды в контексте функции с помощью if..else . Поскольку переменные data не найдены в локальном пространстве имен ( if..else context , это будет выглядеть в непосредственном родительском, т.е. контексте функции, который также не имеет ссылки на data , поэтому он выдает ошибку UnboundLocalError

Чтобы решить эту проблему, вам необходимо включить data из пространства имен модулей в пространство имен функций с помощью globals data оператора, чтобы все вложенные среды внутри функции могли обращаться к ним (Отказ от ответственности: это упрощение того, как внутренние элементы обрабатывают область охвата)

Надеюсь это поможет!


Есть идеи?

10000