А зачем тебе while True вообще?
У тебя значения before и after внутри процедуры НИКОГДА не изменятся.
Для следующего события процедура будет вызвана заново.
Ну а я что говорил? Переводы строк
'A\n' != 'A'
после
a, b, c = lines[i].split(' ')
сделай
c = c.rstrip()
чтобы обрезать все пробельные символы с конца.
Или, если перевод строки нужен, то сравнивай с 'A\n'
Kryptonit, а почему
for i in range(0, 10):
у вас список сортируется по возрастанию цены, а потом вы в 10 самых дешевых товарах ищете товары, у которых letter - буква А.
1. Такие точно есть?
2. letter у вас точно однобуквенные? Или вам нужно чтобы начинались с А?
3. lines[i].split(' ') - а строки в lines[i] содержат переводы строки или нет?
Kryptonit, погоди, погоди...
A[i].letter=='A' даст на выходе булево выражение. Само по себе это ничего не выведет, разумеется.
Если сделать print(A[i].letter=='A'), получишь в стандартном выводе "True" или "False".
А в твоём случае - не с кодировкой ли проблемы? Русская А и латинская A не равны.
Как линукс-подобные ОС так и Виндоус предоставляют такие механизмы, но они различаются.
Собственно, watchdog как раз и обеспечивает одинаковое поведение на разных платформах.
Так что сначала нужно решить, на какую ОС ты хочешь создать свою реализацию.
Не вполне ясно - то ли сервер должен откликаться по одному IP, то ли должен принимать клиентов с одного IP?
Если первое, то пусть слушает только этот IP? В конфиге есть такая строчка.
Если второе... не уверен. через iptables дропать пакеты на порт OpenVPN если идут не с нужного адреса?
Сергей Ермаков: Что значит "приаттачить"? В Питоне нет такого понятия. Ты хочешь чтобы эти функции вызывались последовательно при каждом вызове исходной функции?
TypeError тебе Питон выдаёт совершенно правильно, для функций операция += не определена вообще. Можно самому написать нужную функциональность, но для этого надо понять в чем она заключается.
Писать код за тебя я, прямо скажем, не стану. Но подсказать могу.
Посмотри метод Socket.Poll() - он позволит тебе определить, пришли ли в сокет новые данные, не выполняя собственно чтение. Ему нужно только два параметра: первый - время ожидания в мс, второй - что проверяем. Тебя интересует проверка чтения и ошибки (режимы SelectRead и SelectError, читай документацию).
Проверку на необходимость завершения потока можно сделать простой булевой переменной (признак останова). True - останавливаемся, False - продолжаем.
Исходящие сообщения удобно хранить в ConcurrentQueue. Т.е. каждый элемент этой коллекции - сообщение, которое надо отправить. В простейшем случае это просто строка.
Тогда логика будет такая (я исхожу из того, что ты понял логику работы в моем ответе):
1. Делаем Poll() на ошибку с нулевым таймаутом, если есть ошибка - прерываем цикл.
2. Проверяем признак останова, если True - прерываем цикл.
3. Проверяем очередь на запись. Пока она не пуста, вытаскиваем одно сообщение и отправляем.
4. Делаем Poll() на чтение, с таймаутом порядка 100 миллисекунд, если сообщит что есть данные - делаем Read(), забираем полученную строку, генерируем событие. Как создавать свои события - много раз уже описано.
И так далее в цикле. Как я уже писал, это стоит делать в отдельном потоке - можно даже запускать по потоку на каждого присоединившегося клиента, так будет проще.
Этот рабочий цикл, в общем-то, пригоден и для клиента, и для сервера. Разница будет лишь в том, что клиент будет коннектиться к серверу и запускать рабочий поток, а сервер - занимать порт, ждать коннекта, и запускать рабочий поток для каждого коннекта.
Сергей Ермаков: Погоди, кажется понял: ты хочешь получать оповещения, что функция была вызвана, при этом остальное поведение функции не должно измениться?
Сергей Ермаков: Можешь пояснить, какого поведения ты хочешь этим добиться? У нас есть три функции - исходная (декорируемая), задекорированная (которую мы создаём на базе исходной), и обработчик, который мы цепляем через +=. Как они должны между собой взаимодействовать?
Я имею ввиду, в декораторе, ты можешь заменить декорируемую функцию объектом по типу того что я описал: обладающим методами __iadd__/__isub__ для обработки операторов +=/-= и методом __call__, в котором будет вызываться декорируемая функция. Но какой конкретно функциональности ты хочешь добиться? Без этого не понять, что должно быть в __iadd__/__isub__.
У тебя значения before и after внутри процедуры НИКОГДА не изменятся.
Для следующего события процедура будет вызвана заново.