gpt4 book ai didi

python - 在扭曲的程序中中断 raw_input

转载 作者:太空狗 更新时间:2023-10-29 21:55:18 26 4
gpt4 key购买 nike

我会引用这个explanation还有这个workaround :

所以我正在做的是:

def interrupted(signum, stackframe):
log.warning('interrupted > Got signal: %s', signum)
menu.quitMenu = True # to stop my code

signal.signal(signal.SIGINT, interrupted) # Handle KeyboardInterrupt

问题是,虽然通知菜单它必须停止,并且很快就会停止,但它现在不能停止,因为它卡在 raw_input 中:

def askUser(self):
current_date = datetime.now().isoformat(' ')
choice = raw_input('%s > ' % current_date)
return choice

因此,由于 twisted 正在删除默认的中断处理程序,因此 raw_input 不会停止。我仍然需要在 ^C 之后按 enter 才能停止。

如何强制停止 raw_input,安装默认中断处理程序,这是扭曲上下文中的问题来源(因为扭曲本身不希望被中断)

我猜这个问题只与 raw_input 无关:任何花费无限时间(或超过预设限制)的函数都应该以某种方式被中断。

是否有可接受的扭曲模式?

编辑

这是完整的测试代码:

from datetime import datetime

class Menu:

def __init__(self):
self.quitMenu = False

def showMenu(self):
print '''

A) Do A
B) Do B

'''

def askUser(self):
current_date = datetime.now().isoformat(' ')
choice = raw_input('%s > Please select option > ' % current_date)
print
return choice

def stopMe(self):
self.quitMenu = True

def alive(self):
return self.quitMenu == False

def doMenuOnce(self):
self.showMenu()
choice = self.askUser()
if not self.alive() : # Maybe somebody has tried to stop the menu while in askUser
return
if choice == 'A' : print 'A selected'
elif choice == 'B' : print 'B selected'
else : print 'ERR: choice %s not supported' % (choice)

def forever(self):
while self.alive():
self.doMenuOnce()

from twisted.internet import reactor, threads
import signal

class MenuTwisted:

def __init__(self, menu):
self.menu = menu
signal.signal(signal.SIGINT, self.interrupted) # Handle KeyboardInterrupt

def interrupted(self, signum, stackframe):
print 'Interrupted!'
self.menu.stopMe()

def doMenuOnce(self):
threads.deferToThread(self.menu.doMenuOnce).addCallback(self.forever)

def forever(self, res=None):
if self.menu.alive() :
reactor.callLater(0, self.doMenuOnce)
else :
reactor.callFromThread(reactor.stop)

def run(self):
self.forever()
reactor.run()

我可以用两种不同的方式运行。

正常方式:

menu = Menu()
menu.forever()

^C 立即停止程序:

A) Do A
B) Do B


2013-12-03 11:00:26.288846 > Please select option > ^CTraceback (most recent call last):
File "twisted_keyboard_interrupt.py", line 72, in <module>
menu.forever()
File "twisted_keyboard_interrupt.py", line 43, in forever
self.doMenuOnce()
File "twisted_keyboard_interrupt.py", line 34, in doMenuOnce
choice = self.askUser()
File "twisted_keyboard_interrupt.py", line 22, in askUser
choice = raw_input('%s > Please select option > ' % current_date)
KeyboardInterrupt

正如预期的那样。

扭曲的方式:

menu = Menu()
menutw = MenuTwisted(menu)
menutw.run()

^C 将产生:

A) Do A
B) Do B


2013-12-03 11:04:18.678219 > Please select option > ^CInterrupted!

但是 askUser 实际上并没有被打断:我仍然需要按 enterraw_input 完成。

最佳答案

处理这个问题的正确方法是handle console input asynchronously ,而不是试图使阻塞输入函数可中断。换句话说,raw_input 根本上是您所攻击问题的错误解决方案。

但是,如果您真的只是想了解这里发生了什么,诀窍是在调用 reactor.callFromThread(reactor.stop) 之后,您必须以某种方式提示 raw_input退出;它不会正常。但是,由于您在线程中运行它,它实际上根本不可中断,因为 only the main thread is interruptable在 Python 中。所以我认为你想要的实际上可能是不可能的。我相信也许关闭 sys.stdin 可能会把地毯从 raw_input 下拉出来,即使它在一个线程中,但似乎底层库正在做一些更聪明的事情而不是简单地从 FD 读取,所以关闭它没有好处。

关于python - 在扭曲的程序中中断 raw_input,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20335736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com