目标是在Python2和Python3中持续从
这是因为在Python中,
stdin
读取并强制使用utf8
编码。我尝试了以下解决方案: 我已经尝试过:#!/usr/bin/env python
from __future__ import print_function, unicode_literals
import io
import sys
# Supports Python2 read from stdin and Python3 read from stdin.buffer
# https://dev59.com/5IDba4cB1Zd3GeqPASR5#23932488
user_input = getattr(sys.stdin, 'buffer', sys.stdin)
# Enforcing utf-8 in Python3
# https://dev59.com/_mQn5IYBdhLWcg3wzZ36#16549381
with io.TextIOWrapper(user_input, encoding='utf-8') as fin:
for line in fin:
# Reads the input line by line
# and do something, for e.g. just print line.
print(line)
这段代码在Python3中可以运行,但在Python2中无法使用TextIOWrapper的read函数,并且会抛出以下错误:
Traceback (most recent call last):
File "testfin.py", line 12, in <module>
with io.TextIOWrapper(user_input, encoding='utf-8') as fin:
AttributeError: 'file' object has no attribute 'readable'
这是因为在Python中,
user_input
即sys.stdin.buffer
是一个_io.BufferedReader
对象,它有一个属性readable
: <class '_io.BufferedReader'>
['__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_dealloc_warn', '_finalizing', 'close', 'closed', 'detach', 'fileno', 'flush', 'isatty', 'mode', 'name', 'peek', 'raw', 'read', 'read1', 'readable', 'readinto', 'readinto1', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines']
在Python2中,user_input
是一个文件对象,它的属性没有readable
属性:
<type 'file'>
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
stdin
而不是管道输入。使用stdin
时,它的行为会有所不同。对于Python3中的脚本,在脚本执行之前需要调用enter
然后按下ctr+D
。但在Python中,enter
会刷新缓冲区。 - alvascodecs.StreamReader
,需要重复发送ctrl+D
信号来触发刷新。而我需要发送三个信号才能结束脚本... - lenzio
类,而是应该使用io.open()
。 - lenz