pythonstdin_关于python:从sys.stdin接收输入,非阻塞
我正在为比赛制作机器人,该机器人通过sys.stdin接收其输入,并使用Python的print()作为输出。 我有以下内容:
1
2
3
4
5
6
7
8import sys
def main():
while True:
line = sys.stdin.readline()
parts = line.split()
if len(parts) > 0:
# do stuff
问题在于输入是通过流输入的,并且使用上述输入,使我无法打印任何内容,直到关闭流。 我该怎么做才能使这项工作?
也许重复
在stdin上进行非阻塞要么不起作用,要么不十分可靠。 是否允许使用线程/多处理? 应该起作用的原因
通过关闭阻止功能,您一次只能读取一个字符。因此,没有办法让readline()在非阻塞上下文中工作。我假设您只是想阅读按键来控制机器人。
我在Linux上使用select.select()并没有运气,并通过调整termios设置创建了一种方法。因此,这是特定于Linux的,但对我有用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32old_settings=None
def init_anykey():
global old_settings
old_settings = termios.tcgetattr(sys.stdin)
new_settings = termios.tcgetattr(sys.stdin)
new_settings[3] = new_settings[3] & ~(termios.ECHO | termios.ICANON) # lflags
new_settings[6][termios.VMIN] = 0 # cc
new_settings[6][termios.VTIME] = 0 # cc
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, new_settings)
@atexit.register
def term_anykey():
global old_settings
if old_settings:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
def anykey():
ch_set = []
ch = os.read(sys.stdin.fileno(), 1)
while ch != None and len(ch) > 0:
ch_set.append( ord(ch[0]) )
ch = os.read(sys.stdin.fileno(), 1)
return ch_set;
init_anykey()
while True:
key = anykey()
if key != None:
print key
else:
time.sleep(0.1)
更好的Windows或跨平台答案在这里:Python非阻塞控制台输入
请注意,这也会使终端"不回声":未显示按键。 这是实现此目的的另一种优雅方式:ballingt.com/nonblocking-stdin-in-python-3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#-----------------------------------------------------------------------
# Get a character from the keyboard. If Block is True wait for input,
# else return any available character or throw an exception if none is
# available. Ctrl+C isn't handled and continues to generate the usual
# SIGINT signal, but special keys like the arrows return the expected
# escape sequences.
#
# This requires:
#
# import sys, select
#
# This was tested using python 2.7 on Mac OS X. It will work on any
# Linux system, but will likely fail on Windows due to select/stdin
# limitations.
#-----------------------------------------------------------------------
def GetChar(Block=True):
if Block or select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []):
return sys.stdin.read(1)
raise error('NoChar')
我相信我曾经在Linux上尝试过,但我认为它没有用。 但是,在Mac上我现在正在使用,它绝对不起作用。 无论block是true还是false,它仍然会阻塞。 此外,用户必须按Enter键才能释放积累的字符"泛滥"。 也许尝试将输入模式设置为raw(tty.setraw()),但是之后必须将其设置为煮熟模式。
您可以使用选择器来处理I / O多路复用:
https://docs.python.org/3/library/selectors.html
试试看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#! /usr/bin/python3
import sys
import fcntl
import os
import selectors
# set sys.stdin non-blocking
orig_fl = fcntl.fcntl(sys.stdin, fcntl.F_GETFL)
fcntl.fcntl(sys.stdin, fcntl.F_SETFL, orig_fl | os.O_NONBLOCK)
# function to be called when enter is pressed
def got_keyboard_data(stdin):
print('Keyboard input: {}'.format(stdin.read()))
# register event
m_selector = selectors.DefaultSelector()
m_selector.register(sys.stdin, selectors.EVENT_READ, got_keyboard_data)
while True:
sys.stdout.write('Type something and hit enter: ')
sys.stdout.flush()
for k, mask in m_selector.select():
callback = k.data
callback(k.fileobj)
上面的代码将保留
1for k, mask in m_selector.select():
直到发生注册的事件为止,返回选择器(key)实例(k)和受监视事件的掩码。
在上面的示例中,我们仅注册了一个事件(按Enter键):
1m_selector.register(sys.stdin, selectors.EVENT_READ, got_keyboard_data)
选择器键实例定义如下:
1abstractmethod register(fileobj, events, data=None)
因此,register方法将k.data设置为我们的回调函数got_keyboard_data,并在按下Enter键时调用它:
1
2callback = k.data
callback(k.fileobj)
一个更完整的示例(希望更有用)是将来自用户的标准输入数据与来自网络的传入连接进行复用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76import selectors
import socket
import sys
import os
import fcntl
m_selector = selectors.DefaultSelector()
# set sys.stdin non-blocking
def set_input_nonblocking():
orig_fl = fcntl.fcntl(sys.stdin, fcntl.F_GETFL)
fcntl.fcntl(sys.stdin, fcntl.F_SETFL, orig_fl | os.O_NONBLOCK)
def create_socket(port, max_conn):
server_addr = ('localhost', port)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.setblocking(False)
server.bind(server_addr)
server.listen(max_conn)
return server
def read(conn, mask):
global GO_ON
client_address = conn.getpeername()
data = conn.recv(1024)
print('Got {} from {}'.format(data, client_address))
if not data:
GO_ON = False
def accept(sock, mask):
new_conn, addr = sock.accept()
new_conn.setblocking(False)
print('Accepting connection from {}'.format(addr))
m_selector.register(new_conn, selectors.EVENT_READ, read)
def quit():
global GO_ON
print('Exiting...')
GO_ON = False
def from_keyboard(arg1, arg2):
line = arg1.read()
if line == 'quit
':
quit()
else:
print('User input: {}'.format(line))
GO_ON = True
set_input_nonblocking()
# listen to port 10000, at most 10 connections
server = create_socket(10000, 10)
m_selector.register(server, selectors.EVENT_READ, accept)
m_selector.register(sys.stdin, selectors.EVENT_READ, from_keyboard)
while GO_ON:
sys.stdout.write('>>> ')
sys.stdout.flush()
for k, mask in m_selector.select():
callback = k.data
callback(k.fileobj, mask)
# unregister events
m_selector.unregister(sys.stdin)
# close connection
server.shutdown()
server.close()
# close select
m_selector.close()
您可以使用两个终端进行测试。
第一航站楼:
1
2$ python3 test.py
>>> bla
打开另一个终端并运行:
1
2$ nc localhost 10000
hey!
回到第一
1>>> qwerqwer
结果(在主终端上看到):
1
2
3
4
5
6
7
8
9
10
11$ python3 test.py
>>> bla
User input: bla
>>> Accepting connection from ('127.0.0.1', 39598)
>>> Got b'hey!
' from ('127.0.0.1', 39598)
>>> qwerqwer
User input: qwerqwer
>>>
请在您的帖子中添加说明,以便将来的访问者清楚易懂
我可以建议nobreak吗?如果不是,您愿意使用诅咒。
https://docs.python.org/3/library/curses.html#curses.window.nodelay
使用发电机-幸运的是sys.stdin已经是发电机!
生成器使您可以处理无限流。始终在调用它时会返回下一个元素。为了构建生成器,您需要yield关键字。
1
2
3
4
5for line in sys.stdin:
print line
if a_certain_situation_happens:
break
如果发生某些希望的情况,请不要忘记在循环中放置break语句。
您可以在以下位置找到有关生成器的更多信息:
http://www.dabeaz.com/generators/index.html
http://linuxgazette.net/100/pramode.html
阿伦特还有其他因素在起作用吗? 例如流是行缓冲还是块缓冲?
sys.stdin已经是一个生成器,因此您可以执行for line in sys.stdin: ...或使用更新的fileinput模块。 两者都不是非阻塞的。
pythonstdin_关于python:从sys.stdin接收输入,非阻塞相关推荐
- python input sys.stdin
import sys a=sys.stdin.readline() # 包含了换行符,一般都要使用strip b=input() # 不包含换行符`\n` print(len(a),len(b)) # ...
- linux中c语言kbhit函数用法,C语言判断用户是否输入-非阻塞函数kbhit
一.基础研究 要从地址读取数据,肯定是要定义一个指针变量p,用它来实现变换地址和取值的功能.另外程序是当两个条件中的某一个出现时才停止,所以应该用while~do循环语句循环输出n和d,并用while ...
- python stdout.read()阻塞_通过阅读python subprocess源码尝试实现非阻塞读取stdout以及非阻塞wait...
http://blog.chinaunix.net/uid-23504396-id-4661783.html 执行subprocess的时候,执行不是问题 最麻烦的是获取进程执行后的回显来确认是否正确 ...
- python中showinfo_python – Tkinter中的非阻塞信息对话框
我需要一个简单的信息框来显示一些状态输出,我可以使用print将其转储到控制台.我找到的最简单的可能性如下: import Tkinter as tk root = tk.Tk() root.with ...
- pythonstdin_python 笔试输入:sys.stdin.readline和input
①:输入一行数据并输 出两种方法 # 输入一行数据并输出 import sys # 方法一: str1 = input() print('input 输入:',str1,'len=',len(str1 ...
- 【Python】sys库介绍
sys库 sys模块是最常用的和python解释器交互的模块,sys模块可供访问由解释器(interpreter)使用或维护的变量和与解释器进行交互的函数.sys 模块提供了许多函数和变量来处理 Py ...
- Python读取多行键盘输入
机考处理键盘输入 处理一行键盘输入 对于多元输入 n,k,m=map(int,input().split()) 方法一: line=list(map(str,input().split()))#将输入 ...
- python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)...
python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程并行与并发同步与异步阻塞与非阻塞CPU密集型与IO密集型 线程与进程 进程 前言 ...
- python中sys.stdout、sys.stdin
如果需要更好的控制输出,而print不能满足需求,sys.stdout,sys.stdin,sys.stderr就是你需要的. 1. sys.stdout与print: 在python中调用print ...
- Python的sys.stdout、sys.stdin重定向
Python的sys.stdout.sys.stdin重定向 转自:http://www.cnblogs.com/turtle-fly/p/3280519.html 本文环境:Python 2.7 使 ...
最新文章
- java实现excel的导入导出(poi详解)
- 【Groovy】Groovy 方法调用 ( Groovy 构造函数中为成员赋值 | Groovy 函数的参数传递与键值对参数 | 完整代码示例 )
- python三种数据类型详解_最全面的Python数据类型知识点讲解
- mysql pl安装教程_ubuntu 16 mysql安装包安装 (推荐在线安装)
- mysql instead of_mysqluniqueoptionprefixmyisam_recoverinsteadofmyisam-recover-options的解决方法
- C++学习笔记(二)
- python scatter 简书_写给 Pythonist 的 Spacemacs 入门指北
- 2010年高教社杯全国大学生数学建模竞赛题目B题解析及层次分析法AHP在其中的应用
- 【ruby】ruby学习笔记之--环境搭建
- Linux下PhpMyAdmin程序目录的安全管理
- java枚举返回字符串_枚举工具类-通过给定值获取对应的枚举类
- 天津成人高考计算机基础知识题库,天津市成考《计算机基础考试大纲》(高中起点)...
- 为什么不要随便点击下载链接:过时的远程病毒灰鸽子木马示范
- 为何数据库也云原生了?
- Mac中安装软件的传送门
- 惠普g7服务器硬盘阵列,HP DL388 G7 服务器重新做RAID
- 检测手机号码是否合法(正则表达式)
- A006-AndroidManifest.xml解析
- win10开始菜单打不开了,我屮艸芔茻
- 做外贸开发客户用的邮件群发软件,同行达40%~70%打开率?
热门文章
- 使用css3制作正六面体
- 电磁兼容试验和测量技术标准 GB 17626 简介
- 我的自定义知乎首页及问题页的样子
- [Cnbeta]企业与家用无线路由器的区别
- 滑雪计时系统|滑雪计时计分|2019国际冬季运动(北京)博览会
- CPAN下载安装pm包方法
- ①、iOS-RxSwift基础控件的使用、RxSwift-Tableview的使用、RxSwift-SectionTableview结合RxDataSources使用、RxSwift 网络请求封装使用
- linux vi如何输入井号,Linux Vi命令用法详解
- NLP task2 N-Gram
- jQuery中的siblings()