【问题标题】:Python IDLE running code differently than other IDEsPython IDLE 运行代码与其他 IDE 不同
【发布时间】:2018-10-11 00:16:53
【问题描述】:

我正在尝试让线程与 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 文本编辑器等)上都会这样做:

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

但是,在 Python 自己的 IDLE 中,线程似乎无法打印任何内容,直到我按下 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 中运行,因此它需要在这里工作。

【问题讨论】:

  • 我不认为有可能对此做任何事情。
  • 如果从命令行运行代码,代码是否正常运行?
  • Megalng - 显然是这样,除非我还缺少其他东西。
  • nerak99 - 你可能在那里提供了帮助,因为它可以在命令行上完美运行,而不是通过 IDLE。现在我知道了这一点,我可能可以忍受这个问题,因为它不会影响最终结果,但我对为什么会发生这种情况很感兴趣。
  • 在下面添加我的答案:IDLE 行为差异已在 CPython 跟踪器上报告为 bugs.python.org/issue39724。需要更多的调试来了解为什么 input() 的 readline 阶段会阻塞输出以及如何不这样做。

标签: python python-idle


【解决方案1】:

正如 IDLE 的名字所暗示的,它主要是一个开发(和学习)环境。它特别针对初学者。用于运行完成的代码充其量只是次要的,通常不是优势。

IDLE Doc chapter 可以在 IDLE 本身中通过 Help => IDLE Help 查看,它有一个 (3.3) 小节 IDLE-console 差异。开始了

除了极少数例外,使用 IDLE 执行 Python 代码的结果与在控制台窗口中执行相同代码的结果相同。但是,不同的界面和操作有时会影响可见的结果。

操作上的最大区别在于您的代码在单独的 Python 进程中执行,标准输入和输出通过套接字连接。这意味着您程序的所有 stdout 输出都经过 IDLE 代码,该代码将其插入到 tk Text 小部件中,而不是直接发送到 OS 屏幕管理器。

在 input() 的情况下,IDLE 停止显示输出,直到用户点击返回。 (即使提示为空也是如此。)我认为这是对在用户输入中间散布输出的改进。您的代码无法按原样运行,但以下代码可以。

导入线程,时间

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

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

在 Win10 上的 IDLE 3.7.0b3 中,我看到类似

Hit enter to finish...skjfsjflsjfljsflsfjls
Interruption from threadskjfsjflsjfljsflsfjls

(我不知道为什么 'thread' 后面的 '\n' 被抑制了。) 在命令提示符中我看到了

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()

使用空闲:

>>> Interruption from thread
if a = 3:

在命令提示符中以相同的时间输入相同的标题:

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

如果我能更好地理解相关的 IDLE 代码,我会将中断行插入到提示符之前的一行。我也可能在 input() 期间做同样的事情。幸运的是,线程或异步任务的输出并不常见,尤其是对于初学者而言。

ADDENDUM:如果从命令行使用python -m idlelib -n 运行 IDLE,它会在一个进程中运行并且线程输出不会被阻塞。不知道这个模式会不会出现其他问题(目前没有测试)。

我们(IDLE 维护者)已经同意应该在正常的两个进程模式下停止阻塞,并且知道它发生的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多