Python IDLE выполняет код не так, как другие IDE - PullRequest
0 голосов
/ 01 мая 2018

Я пытаюсь настроить многопоточность для работы с сетью Socket для приема клиентов. У меня это работало нормально, но теперь я обнаружил проблему.

Вот код:

clients = []

def myFunction():    #Not too relevant I think
    server.listen(0)
    conn, addr = server.accept()
    print(conn)
    clients.append(conn, addr)
    threading.Thread(myFunction)

threading.Thread(myFunction)
input("Hit enter to finish...")
print(clients)

Теперь это должно вернуть что-то вроде этого, что происходит во всех IDE, которые я пробовал (PyCharm, Sublime text editor и т. Д.):

Hit enter to finish...
*2 users connect*
192.168.0.5 # this is the contents of conn
192.168.0.12
*hit enter*
192.168.0.5, 192.168.0.12

Однако в собственном IDLE Python многопоточность, кажется, не может ничего напечатать, пока я не нажму Enter, с точно таким же кодом, например, так:

Hit enter to finish...
*2 users connect*
*hit enter*
192.168.0.5
192.168.0.12
192.168.0.5, 192.168.0.12

Это не то, что я хочу, потому что мой код будет работать в Python IDLE после его завершения, поэтому он должен работать здесь из-за этого.

TLDR:
Код работает в Python IDLE иначе, чем в других IDE, с точно таким же кодом. Смотрите приведенные выше примеры кода.

1 Ответ

0 голосов
/ 02 мая 2018

Как следует из названия IDLE, это прежде всего среда разработки (и обучения). Он нацелен прежде всего на начинающих. Использование для запуска готового кода в лучшем случае вторично и обычно не является преимуществом.

Глава IDLE Doc , которую можно просмотреть в самой IDLE с помощью Help => IDLE Help, содержит подраздел (3.3) Различия IDLE-консоли. Начинается

За редкими исключениями результат выполнения кода Python с IDLE должен совпадать с выполнением того же кода в окне консоли. Однако различные интерфейсы и операции иногда влияют на видимые результаты.

Большая разница в работе состоит в том, что ваш код выполняется в отдельном процессе Python со стандартным вводом и выводом, проходящим через сокетное соединение. Это означает, что весь вывод stdout из вашей программы проходит через код IDLE, который вставляет его в текстовый виджет tk, а не отправляет непосредственно в диспетчер экрана ОС.

В случае input (), IDLE перестает отображать вывод, пока пользователь не нажмет return. (Это верно даже при пустом приглашении.) Я считаю, что это лучше, чем разбрызгивание вывода в середине пользовательского ввода. Ваш код не может работать как есть, но выполняется следующее.

импорт потоков, время

def myFunction():
    time.sleep(1)
    print('Interruption from thread')

thread = threading.Thread(target=myFunction)
thread.start()
s =input("Hit enter to finish...")
print(s)

В IDLE 3.7.0b3 на Win10 я вижу что-то вроде

Hit enter to finish...skjfsjflsjfljsflsfjls
Interruption from threadskjfsjflsjfljsflsfjls

(я не знаю, почему '\ n' после 'thread' подавляется.) В командной строке я вижу

Hit enter to finish...ksjfkjsInterruption from thread
fjsfjsfkjsfljksfjkfs
ksjfkjsfjsfjsfkjsfljksfjkfs

Та же проблема возникает при вводе кода после >>> :. Измените мой код на

import threading, time

def myFunction():
    time.sleep(2)
    print('Interruption from thread')

thread = threading.Thread(target=myFunction)
thread.start()

с IDLE:

>>> Interruption from thread
if a = 3:

В командной строке введите тот же заголовок с тем же временем:

C:\Users\Terry>python -i -m a.tem
>>> if aInterruption from thread
 = 3

Если бы я лучше понял соответствующий код IDLE, я бы вставил строку прерывания в строку перед подсказкой. Я мог бы также сделать то же самое во время ввода (). К счастью, вывод из потоков или асинхронных задач не распространен, особенно для начинающих.

...