如何强制 input() 停止并继续代码流
how to force input() to stop and continue the code flow
即使用户没有输入任何内容,我也需要退出包含输入语句的循环。它也从进程接收参数,并且必须立即评估内容。像这样:
import multiprocessing
def my_function (my_queue):
var = ""
#### some code which finally puts something in the queue ###
my_queue.put(var)
def main():
my_queue = multiprocessing.Queue()
p1 = multiprocessing.Process (target=my_function, args =(my_queue,))
p1.daemon = True
p1.start()
my_var = ""
while (my_queue.empty() is True and my_var == ""):
my_var = input ("enter a parameter for my_var: ")
#### code that evaluates the queue and the input as appropiate
## I want to exit the loop if there's something in the queue even if the user hasn't written anything
这当然行不通。主循环堆叠在输入部分。有任何想法吗?我正在使用 Windows。提前谢谢大家!
试试这个:我们使用 os.kill
从子进程向父进程发送一个信号,这会引发一个我们捕获的异常以逃避 input
函数。
import multiprocessing
import signal
import time
import os
def my_function (my_queue, pid):
var = ""
#### some code which finally puts something in the queue ###
time.sleep(3)
my_queue.put(var)
os.kill(pid, signal.SIGUSR1)
def interrupted(*args):
print('Item added to queue before user input completed.')
raise InterruptedError
def main():
my_queue = multiprocessing.Queue()
p1 = multiprocessing.Process (target=my_function, args =(my_queue,
os.getpid()))
# p1.daemon = True
p1.start()
my_var = ""
try:
signal.signal(signal.SIGUSR1, interrupted)
while (my_queue.empty() is True and my_var == ""):
my_var = input ("enter a parameter for my_var: ")
except InterruptedError:
pass
print('Processing results...')
#### code that evaluates the queue and the input as appropiate
## I want to exit the loop if there's something in the queue even if the user hasn't written anything
if __name__ == '__main__':
main()
以上代码仅适用于 Unix。我不知道以下代码是否有效 cross-platform,但它可能:
import multiprocessing
import signal
import time
import os
def my_function (my_queue, pid):
var = ""
#### some code which finally puts something in the queue ###
time.sleep(3)
my_queue.put(var)
os.kill(pid, signal.SIGINT)
def interrupted(*args):
raise InterruptedError
def main():
print('I am %s!' % os.getpid())
my_queue = multiprocessing.Queue()
p1 = multiprocessing.Process (target=my_function, args =(my_queue,
os.getpid()))
p1.daemon = True
p1.start()
my_var = ""
try:
signal.signal(signal.SIGINT, interrupted)
while (my_queue.empty() is True and my_var == ""):
my_var = input ("enter a parameter for my_var: ")
except InterruptedError:
time.sleep(0.1)
if my_queue.empty():
print('Exiting gracefully...')
return
signal.signal(signal.SIGINT, signal.SIG_DFL)
print('Processing results...')
time.sleep(10)
#### code that evaluates the queue and the input as appropiate
## I want to exit the loop if there's something in the queue even if the user hasn't written anything
if __name__ == '__main__':
main()
一个大概是跨平台的答案,通过滥用 asyncio
模块。
我不完全明白我做了什么,我确信这是错误的形式,但我创建了两个并发任务,一个等待输入,一个检查队列中的值并引发中断错误。由于 return_when='FIRST_EXCEPTION' 设置,both 函数有必要引发异常。我通过异常返回了用户输入,因为该函数从不 returns.
import asyncio
import multiprocessing
import time
from aioconsole import ainput
def my_function(queue):
time.sleep(3)
queue.put(5)
async def my_loop(queue):
while True:
await asyncio.sleep(0.1)
if not queue.empty():
raise InterruptedError
async def my_exceptional_input():
text = await ainput("Enter input:")
raise InterruptedError(text)
async def main():
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=my_function, args=(queue,))
p.start()
task1 = asyncio.create_task(my_exceptional_input())
task2 = asyncio.create_task(my_loop(queue))
result = await asyncio.wait([task1, task2], return_when='FIRST_EXCEPTION')
try:
task2.result()
except asyncio.exceptions.InvalidStateError:
text = str(task1.exception())
except InterruptedError:
text = ""
print('Doing stuff with input %s...' % text)
if __name__ == '__main__':
asyncio.run(main())
编辑:使用 'FIRST_EXCEPTION' 对我来说很愚蠢。我可以这样使用 'FIRST_COMPLETED':
import asyncio
import multiprocessing
import time
from aioconsole import ainput
def my_function(queue):
time.sleep(3)
queue.put(5)
async def my_loop(queue):
while True:
await asyncio.sleep(0.1)
if not queue.empty():
break
async def main():
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=my_function, args=(queue,))
p.start()
task1 = asyncio.create_task(ainput("Enter text:"))
task2 = asyncio.create_task(my_loop(queue))
result = await asyncio.wait([task1, task2], return_when='FIRST_COMPLETED')
try:
text = task1.result()
q = ""
except asyncio.exceptions.InvalidStateError:
text = ""
q = queue.get()
print('Doing stuff with input %s/%s...' % (text, q))
if __name__ == '__main__':
asyncio.run(main())
即使用户没有输入任何内容,我也需要退出包含输入语句的循环。它也从进程接收参数,并且必须立即评估内容。像这样:
import multiprocessing
def my_function (my_queue):
var = ""
#### some code which finally puts something in the queue ###
my_queue.put(var)
def main():
my_queue = multiprocessing.Queue()
p1 = multiprocessing.Process (target=my_function, args =(my_queue,))
p1.daemon = True
p1.start()
my_var = ""
while (my_queue.empty() is True and my_var == ""):
my_var = input ("enter a parameter for my_var: ")
#### code that evaluates the queue and the input as appropiate
## I want to exit the loop if there's something in the queue even if the user hasn't written anything
这当然行不通。主循环堆叠在输入部分。有任何想法吗?我正在使用 Windows。提前谢谢大家!
试试这个:我们使用 os.kill
从子进程向父进程发送一个信号,这会引发一个我们捕获的异常以逃避 input
函数。
import multiprocessing
import signal
import time
import os
def my_function (my_queue, pid):
var = ""
#### some code which finally puts something in the queue ###
time.sleep(3)
my_queue.put(var)
os.kill(pid, signal.SIGUSR1)
def interrupted(*args):
print('Item added to queue before user input completed.')
raise InterruptedError
def main():
my_queue = multiprocessing.Queue()
p1 = multiprocessing.Process (target=my_function, args =(my_queue,
os.getpid()))
# p1.daemon = True
p1.start()
my_var = ""
try:
signal.signal(signal.SIGUSR1, interrupted)
while (my_queue.empty() is True and my_var == ""):
my_var = input ("enter a parameter for my_var: ")
except InterruptedError:
pass
print('Processing results...')
#### code that evaluates the queue and the input as appropiate
## I want to exit the loop if there's something in the queue even if the user hasn't written anything
if __name__ == '__main__':
main()
以上代码仅适用于 Unix。我不知道以下代码是否有效 cross-platform,但它可能:
import multiprocessing
import signal
import time
import os
def my_function (my_queue, pid):
var = ""
#### some code which finally puts something in the queue ###
time.sleep(3)
my_queue.put(var)
os.kill(pid, signal.SIGINT)
def interrupted(*args):
raise InterruptedError
def main():
print('I am %s!' % os.getpid())
my_queue = multiprocessing.Queue()
p1 = multiprocessing.Process (target=my_function, args =(my_queue,
os.getpid()))
p1.daemon = True
p1.start()
my_var = ""
try:
signal.signal(signal.SIGINT, interrupted)
while (my_queue.empty() is True and my_var == ""):
my_var = input ("enter a parameter for my_var: ")
except InterruptedError:
time.sleep(0.1)
if my_queue.empty():
print('Exiting gracefully...')
return
signal.signal(signal.SIGINT, signal.SIG_DFL)
print('Processing results...')
time.sleep(10)
#### code that evaluates the queue and the input as appropiate
## I want to exit the loop if there's something in the queue even if the user hasn't written anything
if __name__ == '__main__':
main()
一个大概是跨平台的答案,通过滥用 asyncio
模块。
我不完全明白我做了什么,我确信这是错误的形式,但我创建了两个并发任务,一个等待输入,一个检查队列中的值并引发中断错误。由于 return_when='FIRST_EXCEPTION' 设置,both 函数有必要引发异常。我通过异常返回了用户输入,因为该函数从不 returns.
import asyncio
import multiprocessing
import time
from aioconsole import ainput
def my_function(queue):
time.sleep(3)
queue.put(5)
async def my_loop(queue):
while True:
await asyncio.sleep(0.1)
if not queue.empty():
raise InterruptedError
async def my_exceptional_input():
text = await ainput("Enter input:")
raise InterruptedError(text)
async def main():
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=my_function, args=(queue,))
p.start()
task1 = asyncio.create_task(my_exceptional_input())
task2 = asyncio.create_task(my_loop(queue))
result = await asyncio.wait([task1, task2], return_when='FIRST_EXCEPTION')
try:
task2.result()
except asyncio.exceptions.InvalidStateError:
text = str(task1.exception())
except InterruptedError:
text = ""
print('Doing stuff with input %s...' % text)
if __name__ == '__main__':
asyncio.run(main())
编辑:使用 'FIRST_EXCEPTION' 对我来说很愚蠢。我可以这样使用 'FIRST_COMPLETED':
import asyncio
import multiprocessing
import time
from aioconsole import ainput
def my_function(queue):
time.sleep(3)
queue.put(5)
async def my_loop(queue):
while True:
await asyncio.sleep(0.1)
if not queue.empty():
break
async def main():
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=my_function, args=(queue,))
p.start()
task1 = asyncio.create_task(ainput("Enter text:"))
task2 = asyncio.create_task(my_loop(queue))
result = await asyncio.wait([task1, task2], return_when='FIRST_COMPLETED')
try:
text = task1.result()
q = ""
except asyncio.exceptions.InvalidStateError:
text = ""
q = queue.get()
print('Doing stuff with input %s/%s...' % (text, q))
if __name__ == '__main__':
asyncio.run(main())