Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中捕获任意时间的用户输入_Python_Linux_Input_Interrupt - Fatal编程技术网

在python中捕获任意时间的用户输入

在python中捕获任意时间的用户输入,python,linux,input,interrupt,Python,Linux,Input,Interrupt,当用户在控制台中输入内容时,是否有方法向python模块发送中断?例如,如果我正在运行一个无限while循环,我可以用try/except-For-KeyboardInterrupt围绕它,然后在except块中执行我需要执行的操作 有没有办法用任意输入复制此功能?是控制序列还是标准字符 编辑:很抱歉,这是在linux上的。键盘中断的特殊之处在于它可以被捕获(即,在具有相应POSIX支持的操作系统下的SIGINT,在Windows上的SetConsoletrlHandler)并相应地处理。如果您

当用户在控制台中输入内容时,是否有方法向python模块发送中断?例如,如果我正在运行一个无限while循环,我可以用try/except-For-KeyboardInterrupt围绕它,然后在except块中执行我需要执行的操作

有没有办法用任意输入复制此功能?是控制序列还是标准字符


编辑:很抱歉,这是在linux上的。键盘中断的特殊之处在于它可以被捕获(即,在具有相应POSIX支持的操作系统下的SIGINT,在Windows上的SetConsoletrlHandler)并相应地处理。如果您希望在处理用户输入的同时在其他阻塞循环中执行工作,请查看
线程化
子流程
模块,了解如何在两个不同的线程/进程之间交换数据。另外,请务必了解并行计算的相关问题(即竞争条件、线程安全/同步等)

我不确定这是否是最佳解决方案,但您可以创建一个线程,该线程执行
,而True:sys.stdin.read(1)

这样,您可以始终读取所有输入,但速度会很慢,您必须自己组合字符串

例如:

import os
import sys
import time
import threading

class StdinReader(threading.Thread):
    def run(self):
        while True:
            print repr(sys.stdin.read(1))

os.system('stty raw')

stdin_reader = StdinReader()
stdin_reader.start()

while True:
    time.sleep(1)

os.system('stty sane')

不过,stty raw的
功能取决于运行它的位置。它不会在任何地方都工作。

您需要一个单独的进程(或者可能是一个线程)来读取终端,并通过某种形式的进程间通信(IPC)将其发送给感兴趣的进程(线程间的通信可能会更困难——基本上你唯一要做的就是从一个辅助线程向主线程发送一个
键盘中断。
)。因为你说“我希望有一种简单的方法将用户输入注入循环,而不仅仅是^C”,我很遗憾让您失望,但这是事实:有一些方法可以满足您的要求,但简单的说,它们并不可行。

根据操作系统和可用库的不同,有不同的方法可以实现这一点。提供了一些方法

这是从那里复制的Linux/OS X部分,无限循环使用转义字符终止。对于Windows解决方案,您可以检查答案本身

import sys
import select
import tty
import termios

from curses import ascii

def isData():
    return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])

old_settings = termios.tcgetattr(sys.stdin)
try:
    tty.setcbreak(sys.stdin.fileno())

    i = 0
    while 1:
        print i
        i += 1

        if isData():
            c = sys.stdin.read(1)
            if c == chr(ascii.ESC):
                break

finally:
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)

编辑:将字符检测更改为使用由
curses.ascii
定义的字符,这要感谢Daenyth对我共享的魔法值的不满。

这是我实现我想要的功能的方式,但这并不完全是我的问题所在。因此,如果有人在寻找相同的co,我将发布这篇文章接受,但接受一个更直接的答案


while True:
        try:
            time.sleep( 1 )
            #do stuff
        except KeyboardInterrupt:
            inp = raw_input( '>' )
            if inp == 'i':
                obj.integrate()
            elif inp == 'r':
                obj.reset()

编辑:Guido为我对已接受的答案进行了编辑,因此不再需要此答案

由于穆罕默德所做的更改,已接受的答案不再有效。我已尝试提交更正,但一直被拒绝,因此我会将其作为单独的答案发布。我的代码与他的代码几乎相同,只有一个微小的更改:

import sys
import select
import tty
import termios

from curses import ascii

def isData():
    return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])

old_settings = termios.tcgetattr(sys.stdin)
try:
    tty.setcbreak(sys.stdin.fileno())

    i = 0
    while 1:
        print i
        i += 1

        if isData():
            c = sys.stdin.read(1)
            if c == chr(ascii.ESC):
                break

finally:
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
唯一的区别是我将其改为“c==chr(ascii.ESC)”,而不是“c==ascii.ESC”。我和其他1名开发人员都已测试并确认此更改是必要的,否则程序将无法正常工作


这个程序应该显示越来越大的数字,直到你按下ESC键,然后退出在ascii.ESC周围,它不会检测到您的ESC按键。

是的,我熟悉线程和所有这些,我现在正在开发一个测试函数,我希望有一种简单的方法将用户输入注入循环,而不仅仅是^CLet。要知道,与用户交互从来都不简单!什么操作系统?我不这么认为nk有一种通用的方法。哦,对不起,这是linux。我想我只是假设每个程序员都运行linux>\u不用担心。事实上,这就是我在回答中使用linux示例的原因:)这对我不起作用(在Mac OS X中,但可能没关系),直到我切换回神奇的值“\x1b”。ascii.ESC=27和chr(27)='\x1b'…所以您可能只需要chr(ascii.ESC)。我确认此更改对我有效,并相应地编辑了您的代码,如果我遗漏了什么,请随时恢复!或者更确切地说,任何具有适当代表/访问权限的人,请随时查看我的修复并批准它!我非常确定此代码自2010年以来由于上述原因已被破坏。因此,一人批准了我的编辑,但有三人拒绝了它,也没有办法向他们传达信息——同样,我很确定这段代码已经被破坏了,并且已经使用了3年。python的键盘输入对我来说是一件非常重要的事情。Andrew,soon或vals能否回复告诉我我的修复有什么问题,或者他们是否进行了实际测试?我将尝试重新提交编辑。谢谢!我刚刚在linux上测试过,可以确认murftown所说的话。只有当
ascii.ESC
替换为
chr(ascii.ESC)
时,代码才会按原样工作。谢谢@murftown。我还没有尝试过。但从查看我的编辑来看,很明显,正如你所说,这是我自2010年以来的一次编辑引入的错误。很好!