The default is to use text mode, which may convert '\n' characters to a platform-specific representation on writing and back on reading. Thus, when opening a binary file, you should append 'b' to the mode value to open the file in binary mode, which will improve portability. (Appending 'b' is useful even on systems that don’t treat binary and text files differently, where it serves as documentation.)
When reading input from the stream, if newline is None, universal newlines mode is enabled. Lines in the input can end in '\n', '\r', or '\r\n', and these are translated into '\n' before being returned to the caller. If it is '', universal newlines mode is enabled, but line endings are returned to the caller untranslated.
In text mode, if encoding is not specified the encoding used is platform dependent: locale.getpreferredencoding(False) is called to get the current locale encoding. (For reading and writing raw bytes use binary mode and leave encoding unspecified.)
但是:
'encoding' … should only be used in text mode.
而且,至少从3.3开始,这是强制的;如果尝试使用二进制模式,则会得到ValueError: binary mode doesn't take an encoding argument。
所以,如果您想编写同时在2.x和3.x上工作的代码,您使用什么?如果你想处理bytes,显然f和f1are the same. But if you want to deal instr, as appropriate for each version, the simplest answer is to write different code for each, probablyfandf2`。如果出现很多这样的情况,请考虑编写以下任一包装函数:
Underlying encoded files are always opened in binary mode. No automatic conversion of '\n' is done on reading and writing. The mode argument may be any binary mode acceptable to the built-in open() function; the 'b' is automatically added.
import codecs
with codecs.open('foo', mode='r', encoding='utf8') as f:
# python2: u'foo\r\n'
# python3: 'foo\r\n'
f.readline()
在Python 2.x中:
正如the docs所说:
在Python3.x中,有三种选择:
这将使换行保持未转换,但也将返回
bytes
,而不是str
,您必须亲自将decode
显式地返回到Unicode。(当然,2.x版本也返回了需要手动解码的字节(如果您想要Unicode的话),但在2.x版本中,str
对象就是这样;在3.x版本中,str
是Unicode的。)这将返回
str
,并保留未翻译的换行符。然而,与2.x等价物不同,readline
和friends将把'\r\n'
视为换行符,而不是后跟换行符的正则字符。通常这无关紧要,但如果是的话,请记住。这与2.x代码处理新行的方式完全相同,并且返回
str
使用的编码与使用所有默认值时得到的编码相同…但在当前3.x中不再有效需要为
f3
指定显式编码的原因是,以二进制模式打开文件意味着默认值从“使用locale.getpreferredencoding(False)
解码”更改为“不解码,并返回原始bytes
,而不是str
”。同样,从the docs:但是:
而且,至少从3.3开始,这是强制的;如果尝试使用二进制模式,则会得到
ValueError: binary mode doesn't take an encoding argument
。所以,如果您想编写同时在2.x和3.x上工作的代码,您使用什么?如果你想处理
bytes
,显然f
和f1are the same. But if you want to deal in
str, as appropriate for each version, the simplest answer is to write different code for each, probably
fand
f2`。如果出现很多这样的情况,请考虑编写以下任一包装函数:在编写多版本代码时要注意的另一件事是,如果您没有编写区域设置感知代码,
locale.getpreferredencoding(False)
在3.x中几乎总是返回一些合理的值,但在2.x中通常只返回'US-ASCII'
。使用locale.getpreferredencoding(True)
在技术上是不正确的,但如果你不想考虑编码的话,可能更像是你真正想要的。(尝试在2.x和3.x解释器中同时调用它,以查看原因或阅读文档。)当然,如果你真的知道文件的编码,那总比猜测好。
在这两种情况下,
'r'
都表示“只读”。如果不指定模式,则默认值为'r'
,因此与默认值等效的二进制模式为'rb'
。您需要以二进制模式打开文件:
(
'r'
表示“读取”,'b'
表示“二进制”)然后一切都按原样返回,没有什么是正常化的
您可以使用codecs module来编写“版本不可知”代码:
相关问题 更多 >
编程相关推荐