Функция не "видит" глобальные переменные
В def`ах pif1, pif2 и pif3 указываю global a, b и c соот., и они все между собой работают, но pif4 не хочет их видеть:
import telebot
from cmath import sqrt
bot = telebot.TeleBot("token")
@bot.message_handler(commands=['help', 'start'], content_types=['text'])
def privetstvie(message):
bot.send_message(message.chat.id, 'Бот для счёта a, b (катетов) или c (гипотенузы) в теореме Пифагора\n\nНеобходимо ввести 2 известных числа, а вместо искомого числа отправить команду "Считать"')
@bot.message_handler(commands=['reset', 'count'], content_types=['text'])
def pifna4alo(message):
pn = bot.send_message(message.chat.id, 'Введите a:')
bot.register_next_step_handler(pn, pif1)
def pif1(message):
global a
a = message.text
try:
a = float(a)
p1 = bot.send_message(message.chat.id, 'Введите b:')
bot.register_next_step_handler(p1, pif2)
except:
if(a == '/count'):
p1 = bot.send_message(message.chat.id, 'Введите b:')
bot.register_next_step_handler(p1, pif2)
elif(a == '/reset'):
p1 = bot.send_message(message.chat.id, 'Введите /reset или /count для сброса:')
bot.register_next_step_handler(p1, pifna4alo)
else:
p1 = bot.send_message(message.chat.id, 'Ошибка: выберите "Считать" либо введите значение числа!')
bot.register_next_step_handler(p1, pif1)
def pif2(message):
global b
b = message.text
try:
b = float(b)
p2 = bot.send_message(message.chat.id, 'Введите c:')
bot.register_next_step_handler(p2, pif3)
except:
if(b == '/count'):
if(a == b):
p2 = bot.send_message(message.chat.id, 'Ошибка: считать можно только одно из чисел!')
bot.register_next_step_handler(p2, pif2)
else:
p2 = bot.send_message(message.chat.id, 'Введите c:')
bot.register_next_step_handler(p2, pif3)
elif(b == '/reset'):
p2 = bot.send_message(message.chat.id, 'Введите /reset или /count для сброса:')
bot.register_next_step_handler(p2, pifna4alo)
else:
if(a == '/count'):
p2 = bot.send_message(message.chat.id, 'Ошибка: введите значение числа!')
bot.register_next_step_handler(p2, pif2)
else:
p2 = bot.send_message(message.chat.id, 'Ошибка: выберите "Считать" либо введите значение числа!')
bot.register_next_step_handler(p2, pif2)
def pif3(message):
global c
c = message.text
global p3
try:
c = float(c)
p3 = bot.send_message(message.chat.id, 'Вычисляю...')
bot.register_next_step_handler(p3, pif4)
except:
if(c == '/count'):
if(a == c or b == c):
p3 = bot.send_message(message.chat.id, 'Ошибка: считать можно только одно из чисел!')
bot.register_next_step_handler(p3, pif3)
else:
p3 = bot.send_message(message.chat.id, 'Вычисляю...')
bot.register_next_step_handler(p3, pif4)
elif(c == '/reset'):
p3 = bot.send_message(message.chat.id, 'Введите /reset или /count для сброса:')
bot.register_next_step_handler(p3, pifna4alo)
else:
if(a == '/count' or b == '/count'):
p3 = bot.send_message(message.chat.id, 'Ошибка: введите значение числа!')
bot.register_next_step_handler(p3, pif3)
else:
p3 = bot.send_message(message.chat.id, 'Ошибка: выберите "Считать"!')
bot.register_next_step_handler(p3, pif3)
def pif4():
if(a == '/count'):
a = sqrt(c*c-b*b)
bot.send_message(p3.chat.id, 'Результат: '+str(a.real)+'\n\nЧтобы использовать бота повторно, отправьте любое сообщение')
elif(b == '/count'):
b = sqrt(c*c-a*a)
bot.send_message(p3.chat.id, 'Результат: '+str(b.real)+'\n\nЧтобы использовать бота повторно, отправьте любое сообщение')
elif(c == '/count'):
c = sqrt(a*a+b*b)
bot.send_message(p3.chat.id, 'Результат: '+str(c.real)+'\n\nЧтобы использовать бота повторно, отправьте любое сообщение')
else:
bot.send_message(p3.chat.id, 'КАК ТЫ СЮДА ПОПАЛ?!')
bot.infinity_polling()
Edit: вроде решил, но оставляю этот вопрос как память ._.
Ответы (2 шт):
Вообще ничего не знаю о ботах, телеботах и проч. Но мне всегда кажется антипаттерном использовать глобальные переменные поскольку функции их использующие могут принести изменения и отследить это с ростом программы все труднее и труднее. В любом случае, если вы вынесете свои переменные в начало программы и определите их как пустые со значениями None и будете потом переопределять в функциях-модификаторах (назовем их так), то все должно сработать и они будут видны на всех уровнях функций.
import telebot
from cmath import sqrt
a = None
b = None
c = None
p3 = None
@bot.message_handler(commands=['help', 'start'], content_types=['text'])
.......
Я не вижу причин, по которым надо использовать здесь глобальные переменные. Думаю есть смысл написать функции, которые принимают данные значения как входные параметры.
Разбираться в вашем большом коде сложно, что такое "не хочет их видеть" вы не пояснили:-), да и я "ничего не знаю о ботах, телеботах и проч.", но обратите внимание на упрощённый пример ниже на базе вашего кода. Он работает и для pif4() (см.комментарии). Надеюсь, поможет. (и да - global лучше не использовать, см. объяснение в другом ответе).
И поясните всё же в комменте, что значит "не хочет их видеть":-)
Вообще, global в Python работает несколько "необычно", для любителей С, например.
def pif1():
global a
a = 5
print('pif1:', a) # Печатает: pif1: 5
def pif2():
global b
b = 6
print('pif2:', a, b) # Печатает: pif2: 5 6
def pif3():
global c
c = 7
print('pif3:', a, b, c) # Печатает: pif3: 5 6 7
pif4 ()
def pif4():
print('pif4:', a, b, c) # Печатает: pif4: 5 6 7
pif1()
pif2()
pif3()