为什么我要preSS Ctrl + D键两次,关闭标准输入? [英] Why do I have to press Ctrl+D twice to close stdin?

查看:370
本文介绍了为什么我要preSS Ctrl + D键两次,关闭标准输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的Python脚本读取数字并输出一个错误,如果输入的不是一个数字。

 进口的FileInput
进口SYS
在线路(txt.strip()为TXT在fileinput.input()):
    如果不是line.isdigit():
        sys.stderr.write(错误:不是一个数字:%S \\ n%线)

如果我从标准输入输入,我不得不preSS <大骨节病>控制 + <大骨节病> D 两次以结束程序。为什么呢?

我只需要preSS <大骨节病>控制 + <大骨节病> D 有一次,我本身运行的Python间preTER。

 的bash $蟒蛇test.py
1
2

4

&LT;按Ctrl + D&GT;
错误:不是一个数字:富
&LT;按Ctrl + D&GT;
庆典$


解决方案

在Python 3里,这是由于错误在Python的标准I / O库。该错误是固定在Python 3.3。


在UNIX终端,按Ctrl + D并不真正关闭进程的标准输入。但是,无论是打字输入或Ctrl + D确实会导致操作系统系统调用马上回来。所以:

 &GT;&GT;&GT; sys.stdin.read(100)
XYZZY(I preSS在此处输入)
                            (我preSS Ctrl + D键一次)
XYZZY \\ n'
&GT;&GT;&GT;

sys.stdin.read(100)委托给 sys.stdin.buffer.read ,它调用阅读()在一个循环中,直到它积累数据的全部要求的数额制度;或)读取系统(返回0字节;或发生错误。的(文档)(源)

pressing输入的第一行引起的()读取系统以返回6个字节之后。 sys.stdin.buffer.read 阅读称为()再次尝试获得更多的投入。然后我pressed Ctrl + D键,导致阅读()返回0字节。在这一点上,<​​code> sys.stdin.buffer.read 放弃了,刚刚返回更早,它已收集到的6个字节。

请注意,该进程仍然有我的标准输入终端,我仍然可以输入的东西。

 &GT;&GT;&GT; sys.stdin.read()(注意我仍然可以输入东西的python)
XYZZY(I preSS回车)
                            (再次preSS按Ctrl + D)
XYZZY \\ n'

确定。这是当这个问题本来是问被猛击了的部分。它的工作原理吧。但在此之前的Python 3.3,有一个错误。

该缺陷是有点复杂---基本的问题是两个不同的层,做同样的工作。 BufferedReader.read()写调用 self.raw.read(),直到它返回0字节。然而,原始的方法, FileIO.read(),进行它自己的环路,直到零字节。所以你第一次preSS按Ctrl + D在Python与此bug,它会导致 FileIO.read() 6个字节返回 BufferedReader.read(),那么它会立即打电话 self.raw.read()一次。第二次按Ctrl + D会导致的的返回0字节,然后 BufferedReader.read()将最终退出。

这解释是不幸的是比我的previous一大部分时间更长,但它的优点是正确的。错误是这样的...

I have the following Python script that reads numbers and outputs an error if the input is not a number.

import fileinput
import sys
for line in (txt.strip() for txt in fileinput.input()):
    if not line.isdigit():
        sys.stderr.write("ERROR: not a number: %s\n" % line)

If I get the input from stdin, I have to press Ctrl + D twice to end the program. Why?

I only have to press Ctrl + D once when I run the Python interpreter by itself.

bash $ python test.py
1
2
foo
4
5
<Ctrl+D>
ERROR: not a number: foo
<Ctrl+D>
bash $

解决方案

In Python 3, this was due to a bug in Python's standard I/O library. The bug was fixed in Python 3.3.


In a Unix terminal, typing Ctrl+D doesn't actually close the process's stdin. But typing either Enter or Ctrl+D does cause the OS read system call to return right away. So:

>>> sys.stdin.read(100)
xyzzy                       (I press Enter here)
                            (I press Ctrl+D once)
'xyzzy\n'
>>>

sys.stdin.read(100) is delegated to sys.stdin.buffer.read, which calls the system read() in a loop until either it accumulates the full requested amount of data; or the system read() returns 0 bytes; or an error occurs. (docs) (source)

Pressing Enter after the first line caused the system read() to return 6 bytes. sys.stdin.buffer.read called read() again to try to get more input. Then I pressed Ctrl+D, causing read() to return 0 bytes. At this point, sys.stdin.buffer.read gave up and returned just the 6 bytes it had collected earlier.

Note that the process still has my terminal on stdin, and I can still type stuff.

>>> sys.stdin.read()        (note I can still type stuff to python)
xyzzy                       (I press Enter)
                            (Press Ctrl+D again)
'xyzzy\n'

OK. This is the part that was busted when this question was originally asked. It works now. But prior to Python 3.3, there was a bug.

The bug was a little complicated --- basically the problem was that two separate layers were doing the same work. BufferedReader.read() was written to call self.raw.read() repeatedly until it returned 0 bytes. However, the raw method, FileIO.read(), performed a loop-until-zero-bytes of its own. So the first time you press Ctrl+D in a Python with this bug, it would cause FileIO.read() to return 6 bytes to BufferedReader.read(), which would then immediately call self.raw.read() again. The second Ctrl+D would cause that to return 0 bytes, and then BufferedReader.read() would finally exit.

This explanation is unfortunately much longer than my previous one, but it has the virtue of being correct. Bugs are like that...

这篇关于为什么我要preSS Ctrl + D键两次,关闭标准输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆