将函数结果写入标准输入(stdin)

15
我是一名有用的助手,可以为您翻译文本。
我正在尝试将函数的结果写入stdin。
这是代码:
def testy():
    return 'Testy !'

import sys
sys.stdin.write(testy())

我得到的错误是:

Traceback (most recent call last):
  File "stdin_test2.py", line 7, in <module>
    sys.stdin.write(testy())
io.UnsupportedOperation: not writable

我不是完全确定,这是否是正确的做法?

4
你想要做什么?stdin是用于读取输入的,它只能以只读方式打开。 - Pavel Anossov
1
是的,我知道。我想要做的是通过写入stdin来模拟按键到input()方法。 - m_vdbeek
1
@Awake 有些上下文会有所帮助:为什么你想要在 input() 中模拟按键? - askewchan
1
因为我有一个最初在 shell 中的程序,现在正在使用 GUI。我想做的是将点击事件转换为字符串(已完成),并将结果传输到先前使用的 input() 方法中。 - m_vdbeek
1
以前我会要求用户输入1、2或3来选择选项,但现在我知道在GUI上有三个地方可以让用户单击。然后将event.x和event.y转换为特殊字符串,并将其传送到input()函数。 - m_vdbeek
显示剩余5条评论
4个回答

28

您可以使用类似文件的对象来模拟 stdin 吗?

import sys
import StringIO

oldstdin = sys.stdin
sys.stdin = StringIO.StringIO('asdlkj')

print raw_input('.')       #  .asdlkj

1
我想尝试这个解决方案。谢谢! - m_vdbeek
8
Python 3的翻译:from io import StringIOsys.stdin = StringIO('asdlkj') - orbeckst
请注意,sys.stdinStringIO并不完全展现相同的行为,反之亦然;例如,StringIO.readline()会立即返回一个空字符串,而不像sys.stdin.readlineinput那样阻塞/等待输入。请参见https://dev59.com/GmLVa4cB1Zd3GeqPtRwF以解决*该*问题。 - Brendano257

2

我曾经在谷歌上搜索如何做到这一点,然后我自己想出了方法。 对于我的情况,我从hackerrank.com中获取一些样本输入并将其放入文件中,然后希望能够使用该文件作为我的stdin,以便我可以编写一个可以轻松拷贝/粘贴到他们的IDE中的解决方案。 我将我的2个Python文件设置为可执行文件,添加了shebang。 第一个文件读取我的文件并写入stdout

#!/Users/ryandines/.local/share/virtualenvs/PythonPractice-U9gvG0nO/bin/python
# my_input.py
import sys

def read_input():
    lines = [line.rstrip('\n') for line in open('/Users/ryandines/Projects/PythonPractice/swfdump')]
    for my_line in lines:
        sys.stdout.write(my_line)
        sys.stdout.write("\n")

read_input()

第二个文件是我编写的解决编程挑战的代码。这是我的代码:
#!/Users/ryandines/.local/share/virtualenvs/PythonPractice-U9gvG0nO/bin/python
def zip_stuff():

    n, x = map(int, input().split(' '))
    sheet = []

    for _ in range(x):
        sheet.append( map(float, input().split(' ')) )

    for i in zip(*sheet): 
        print( sum(i)/len(i) )

zip_stuff()

然后我使用操作系统的管道命令来提供STDIN的缓冲,与hackerrank.com完全相同,因此我可以轻松地复制/粘贴示例输入以及相应的代码,而不需要更改任何内容。像这样调用:./my_input.py | ./zip_stuff.py


嘿,谢谢,这正是我所需要的用例 :) 运行得很好! - Ahndwoo
嘿,Ryan,干得好。你知道吗,你可以直接使用命令行中的文件作为输入,这样你就不需要编写你的第一个程序了吗?或者我漏掉了什么?: ./zip_stuff.py < '/Users/ryandines/Projects/PythonPractice/swfdump' - tharibo
@tharibo 没错,或者只需将文件合并 cat swfdump | ./zip_stuff.py,尽管对于 Hackerrank 我需要一些特定的行为...我不太记得了 TBH - Ryan Dines

1
在Linux上是可以实现的:
import fcntl, termios
import os
tty_path = '/proc/{}/fd/0'.format(os.getpid())

with open(tty_path, 'w') as tty_fd:
        for b in 'Testy !\n':
            fcntl.ioctl(tty_fd, termios.TIOCSTI,b)
# input()


0

stdin 是一个输入流,而不是输出流。你不能向它写入数据。

可能的解决方法是使用 os.pipe 创建一个管道,使用 os.fdopen 将可读端转换为文件对象,并将其替换为 stdin,然后向可写端写入数据。

r, w = os.pipe()
new_stdin = os.fdopen(r, 'r')
old_stdin, sys.stdin = sys.stdin, new_stdin

我觉得这样做不会有好结果。最好的方法是重写你的应用程序中使用了 input 的部分,这样更容易且减少错误。


1
虽然它并没有解决这个问题,但是事实证明你可以写入stdin - The Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接