Вопрос или проблема
Я пишу скрипт на Python с использованием PySimpleGUI, однако сталкиваюсь с проблемами в том, как реализовать условные операторы, когда нажимается кнопка.
Когда нажимается кнопка “Сгенерировать прокси”, сначала необходимо проверить, есть ли действительный токен, если токен недействителен или токена нет, итерация должна завершиться. Однако я не могу использовать return, так как это не функция, я пытался определить некоторые условия в check_token() и check_country(), однако не знаю, как правильно это реализовать.
Учитывая, что для выполнения кнопки необходим действительный токен перед проверкой страны и других элементов (таких как счетчик), есть ли возможность остановить итерацию кнопки, чтобы дать пользователю возможность получить токен или исправить поля для страны или других параметров перед тем, как все “if” будут проверены в рабочем процессе? Каков будет лучший способ это сделать?
(Я пытался проверить с ChatGPT, и он порекомендовал использовать return или break в рабочем процессе кнопки. Что не помогает, потому что [1] return используется только в функциях, [2] break закроет все приложение, когда оно работает.)
Я пытался реализовать условные операторы непосредственно в кнопке, однако, чтобы использовать return для кнопки, я написал две функции, чтобы помочь мне получить информацию. Я боюсь, что не извлекаю логическое значение из функций правильно, чтобы использовать его в качестве ссылки в условии.
[Кнопка PySimpleGUI]
elif event == "Сгенерировать прокси":
output_element = window['output']
proxy_list_element = window['proxy_list']
timestamp = app.log_time_stamp()
output_element.update(f"[{timestamp}] 'Сгенерировать прокси' нажата\n", append=True)
country = values['country'].upper()
region = values['region']
city = values['city']
count = values['count']
# УСЛОВИЯ
if not check_token(token):
print("Недействительный вывод. Вина токена, который не существует. Тестируя break.")
break
if check_country(country):
pass
if not region or not city:
sleep(2)
output_element.update(f"[{timestamp}] Город и регион оба являются опциональными полями. Вам не нужно их указывать.\n", append=True)
pass
if not count or not count.isdigit():
sleep(2)
output_element.update(f"[{timestamp}] Поле 'Количество' пустое. Пожалуйста, укажите количество прокси, которые вы хотите в вашем списке.\n", append=True)
sleep(2)
# break
else:
sleep(2)
output_element.update(f"[{timestamp}] Количество: {count}.\n", append=True)
try:
if values['sticky_session'] == 'Сохранить IP как можно дольше':
session_type="sticky"
else:
session_type="custom"
protocol="socks5" if values['SOCKS5'] else 'HTTP'
sleep(2)
output_element.update(f"[{timestamp}] Запрос: Страна: {country}, Регион: {region}, Город: {city}, Постоянная сессия: {session_type}, Протокол: {protocol}, Количество: {count}.\n", append=True)
sleep(2)
output_element.update(f"[{timestamp}] Отправка запроса... Пожалуйста, подождите.\n", append=True)
sleep(2)
proxy_list = mlx.get_proxy(
country, region, city, session_type, protocol, count)
for proxy in proxy_list:
proxy_list_element.update(f"{proxy}\n")
except Exception as e:
sg.Print("Окно журнала инициализировано...", do_not_reroute_stdout=False)
sg.Print(f"Произошла ошибка: {e}.\n")
sg.Print(traceback.format_exc())`
[ПРОВЕРКА ТОКЕНА]
def check_token(token):output_element = window['output']timestamp = mlx.log_time_stamp()
if not token:
output_element.update(f"[{timestamp}] Вы должны использовать свое имя пользователя и пароль, чтобы СНАЧАЛА ПОЛУЧИТЬ ТОКЕН.\n", append=True)
sleep(1)
output_element.update(f"[{timestamp}] Продолжение невозможно без токена. Отмена запроса.\n", append=True)
sleep(1)
output_element.update(f"[{timestamp}] Попробуйте еще раз.\n", append=True)
return False
output_element.update(f"[{timestamp}] Существующий токен. Начинаем запрос.\n", append=True)
return True
[функция check_country()]
def check_country(country):
output_element = window['output']
timestamp = mlx.log_time_stamp()
if not country:
sleep(2)
output_element.update(f"[{timestamp}] [ОШИБКА] Пожалуйста, введите страну в поле Страна. Это обязательное поле. Вы должны использовать формат ISO 3166-1 alpha-2 (например, US, FR, BR).\n", append=True)
sleep(1)
return
if len(country) != 2 or country not in iso_country_codes:
sleep(2)
sg.Print("[ОШИБКА] В введенной стране нет действительного значения.\n", append=True) sg.Print(traceback.format_exc())
output_element.update(f"[{timestamp}] {country} не является действительным значением для страны. Вы должны использовать формат ISO 3166-1 alpha-2 (например, US, FR, BR).\n", append=True)
sleep(1)
return
sleep(2)
output_element.update(f"[{timestamp}] {country} является действительным. Продолжаем запрос\n", append=True) sleep(1)
return True
Что я ожидаю?
Когда нажимается кнопка “Сгенерировать прокси”, проверяется, есть ли действительный токен. Если нет, то останавливается кнопка, чтобы дать пользователю возможность сгенерировать токен. Если токен действителен, проверяются страна, регион, город, сессия, протокол и количество. Сессия и протокол уже имеют значения по умолчанию, тогда как регион и город не являются обязательными. Токен, страна и количество являются обязательными (пользователь предоставляет их), чтобы отправить в API-запрос для получения ответа (он будет показан в элементе с несколькими строками “proxy_list”.
Не уверен, в чем именно вопрос, так что здесь простой ответ на него.
def valid_token(token):
return True
def valid_args(*args):
return True, args
while True:
event, values = window.read()
if event == sg.WIN_CLOSE():
break
elif event == "Сгенерировать прокси":
token = values["token"]
if not valid_token(token):
continue # "continue" здесь, не "break"
args = (values[key] for key in ("country", "region", "city", "session", "protocol", "count"))
valid, args = valid_args(*args)
if valid:
response = request(*args)
window.close()
Ответ или решение
Для решения вашей проблемы с реализацией логики условных операторов в скрипте Python с использованием PySimpleGUI, мы можем применить несколько ключевых подходов, которые помогут контролировать поток выполнения программы при нажатии кнопки "Generate Proxy". Рассмотрим детально, как можно структурировать ваше решение.
Структурирование кода
-
Проверка условия токена: Для обеспечения корректного выполнения вашего скрипта необходимо первым делом проверять наличие и валидность токена. Если токен недействителен или отсутствует, выполнение дальнейших действий будет прервано.
-
Прерывание итераций и возврат: Вместо использования
break
, который завершает цикл обработки событий, вы можете использоватьcontinue
, чтобы пропустить текущую итерацию и вернуться к обработке событий. -
Оптимизация показателей: Ваша логика по проверке различных параметров (страна, город, количество) также должна быть разбита на отдельные функции. Эти функции могут возвращать булевы значения, которые вы можете проверять в основным цикле.
Пример реализации
Ниже приведен пример того, как вы можете реализовать предложенные изменения:
def check_token(token):
output_element = window['output']
timestamp = mlx.log_time_stamp()
if not token:
output_element.update(f"[{timestamp}] Вы должны получить токен перед продолжением.\n", append=True)
return False
output_element.update(f"[{timestamp}] Токен действителен. Начинаем запрос.\n", append=True)
return True
def check_country(country):
output_element = window['output']
timestamp = mlx.log_time_stamp()
if not country or len(country) != 2 or country not in iso_country_codes:
output_element.update(f"[{timestamp}] Неверный формат страны. Используйте ISO 3166-1 alpha-2.\n", append=True)
return False
output_element.update(f"[{timestamp}] Страна {country} валидна. Продолжаем запрос.\n", append=True)
return True
def check_count(count):
output_element = window['output']
timestamp = mlx.log_time_stamp()
if not count or not count.isdigit():
output_element.update(f"[{timestamp}] Поле 'Count' пусто или некорректно. Укажите количество.\n", append=True)
return False
return True
# Основной цикл обработки событий
while True:
event, values = window.read()
if event == sg.WIN_CLOSE():
break
elif event == "Generate Proxy":
output_element = window['output']
timestamp = mlx.log_time_stamp()
token = values['token']
if not check_token(token):
continue # вернуться к началу цикла
country = values['country'].upper()
if not check_country(country):
continue # вернуться к началу цикла
region = values['region']
city = values['city']
count = values['count']
if not check_count(count):
continue # вернуться к началу цикла
# Логика выполнения запроса к API
try:
session_type = "sticky" if values['sticky_session'] == 'Keep IP as long as possible' else "custom"
protocol = "socks5" if values['SOCKS5'] else 'HTTP'
# Отправка запроса
proxy_list = mlx.get_proxy(country, region, city, session_type, protocol, count)
for proxy in proxy_list:
window['proxy_list'].update(f"{proxy}\n", append=True)
output_element.update(f"[{timestamp}] Запрос отправлен. Полученные прокси: {proxy_list}\n", append=True)
except Exception as e:
sg.Print(f"Произошла ошибка: {e}.\n")
Что учитывает данное решение:
- Структурированность: Каждая проверка вынесена в отдельную функцию, что делает код более читаемым и поддерживаемым.
- Отказ от
break
: Командаcontinue
позволяет избежать приостановки всего приложения и вернуться к началу цикла, а значит, пользователь может внести исправления в поля без выхода из программы. - Информативные сообщения: Пользователь получает четкие сообщения о том, что он должен исправить, прежде чем продолжить.
Заключение
Таким образом, при правильном подходе к обработке условий в вашем приложении PySimpleGUI, вы сможете гарантировать, что программа будет реагировать на действия пользователя адекватно, а также предоставит ему возможность исправлять ошибки без необходимости перезапуска приложения. Ваш код станет более понятным, удобным для поддержки и использования.