Python:等效于使用sys.stdin的输入 [英] Python: equivalent of input using sys.stdin

查看:128
本文介绍了Python:等效于使用sys.stdin的输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想测试一些直接使用printinput函数的(python 3)代码.据我了解,最简单的方法是依赖注入:修改代码,使其将输入和输出流作为参数,默认情况下使用sys.stdinsys.stdout,并在测试过程中传递模拟对象.很明显,如何处理print调用:

I want to test some (python 3) code that directly uses the print and input functions. As I understand it, the easiest way to do this is by dependency injection: modifying the code so that it takes input and output streams as arguments, using sys.stdin and sys.stdout by default and passing in mock objects during testing. It's obvious what to do with print calls:

print(text)
#replaced with...
print(text, file=output_stream)

但是,input没有用于输入和输出流的参数.以下代码是否正确地重现其行为?

However, input doesn't have arguments for input and output streams. Does the following code correctly reproduce its behaviour?

text = input(prompt)
#replaced with...
print(prompt, file=output_stream, end='')
text = input_stream.readline()[:-1]

我看了input的实现,它做了很多魔术,调用sys.stdin.fileno并检查sys.stdin.encodingsys.stdin.errors而不是调用任何read*方法-我不会不知道从哪里开始嘲笑那些.

I had a look at the implementation of input, and it does quite a lot of magic, calling sys.stdin.fileno and examining sys.stdin.encoding and sys.stdin.errors rather than calling any of the read* methods - I wouldn't know where to start with mocking those.

推荐答案

input()仅在未更改stdinstdout时提及的魔术,因为只有这样,它才能使用readline库之类的功能.如果您将它们替换为其他文件(是否为真实文件),它将归结为以下代码:

input() only does the magic you mentioned when stdin and stdout are not altered, because only then it can use things like the readline library. If you replace them with something else (real-files or not) it comes down to this code:

/* Fallback if we're not interactive */
if (promptarg != NULL) {
    if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0)
         return NULL;
}
tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
if (tmp == NULL)
    PyErr_Clear();
else
    Py_DECREF(tmp);
return PyFile_GetLine(fin, -1);

PyFile_GetLine 调用readline 方法.因此,嘲讽sys.std*将起作用.

建议您使用try: finally:,上下文处理器或mock模块来执行此操作,以便即使正在测试的代码因异常而失败,也可以恢复输出:

It's recomended you do this with try: finally:, a context processor or the mock module, so that the outputs are restored even if the code you are testing fails with exceptions:

from unittest.mock import patch
from io import StringIO

with patch("sys.stdin", StringIO("FOO")), patch("sys.stdout", new_callable=StringIO) as mocked_out:
    x = input()
    print("Read:", x)

assert mocked_out.getvalue() == "Read: FOO\n"

这篇关于Python:等效于使用sys.stdin的输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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