Python 3: ошибка 'name '...' is not defined"

Хочу сделать некий "автостатус" для бота, использу. для этого str(status_message_from_cycle) выставляя ему значение в цикле:

def status_cycle1():
    status_message_from_cycle = str("test 1")

def status_cycle2():
    status_message_from_cycle = str("test 2")

interval = 2

def statusPeriodicFunction():
    status_cycle1()
    status_cycle2()

def startTimer():
    threading.Timer(interval, startTimer).start()
    statusPeriodicFunction()

Позже это значение выставляется в конфиге:

self.status_message = str(status_message_from_cycle)

Но после интерпретаций кода выходит:

File "/media/mint/F3D8-BADB/MusicBot/musicbot/config.py", line 88, in init self.status_message = str(status_message_from_cycle) NameError: name 'status_message_from_cycle' is not defined


Ответы (1 шт):

Автор решения: Teivaz

В питон область видимости переменной по умолчанию локальная. К примеру следующий код не изменит глобальную переменную

var_a = "original value"

def modify_var_a():
  var_a = "changed value" # создана новая переменная

modify_var_a()
print(var_a) # >>> original value

Чтобы явно указать использование переменной из внешней области видимости нужно использовать ключевое слово global с названием переменной до того, как она будет использована во внутренней области видимости. Если же есть несколько вложенных областей видимости, то можно получить доступ либо к глобальной области видимости при помощи global, либо же к "ближайшей" используя nonlocal.

var_a = 1

def modify_a():
  var_a = 2 # другая переменная с тем же именем, что и глобальная

  def modify_a1():
    global var_a
    var_a = 3

  modify_a1()

  def modify_a2():
    nonlocal var_a
    var_a = 5

  modify_a2()

  print("modify_a::var_a =", var_a)

modify_a()
print("::var_a =", var_a)

modify_a::var_a = 5
::var_a = 3

Это же происходит и в вашем случае. В функции status_cycle1 создаётся новая переменная status_message_from_cycle но она не выходит за область видимости функции. Нужно сначала создать глобальную, затем в функции указать, что используется именно глобальная, а затем её модифицировать.

→ Ссылка