我一直认为open
和io.open
是可以互换的
显然不是,如果我相信这个片段:
import ctypes, io
class POINT(ctypes.Structure):
_fields_ = [("x", ctypes.c_int),("y", ctypes.c_int)]
# THIS WORKS
with open("mypoints.bin", "wb") as f:
for i in range(10):
p = POINT(i,10-i)
print p.x, p.y
f.write(p)
# THIS FAILS
with io.open("mypoints.bin", "wb") as f:
for i in range(10):
p = POINT(i,10-i)
print p.x, p.y
f.write(p)
0 10
Traceback (most recent call last):
File "D:\test.py", line 10, in <module>
f.write(p)
File "c:\Python26\lib\io.py", line 1070, in write
self._write_buf.extend(b)
TypeError: 'POINT' object is not iterable
注意:我在Python 2.6.6中测试
答案 0 :(得分:7)
是的,这是一个“bug”,Python 2.6中的io.open
略有破解。它应该像3.x的open
一样工作以简化转换,但在某些情况下它无法正常工作。例如,它不支持具有缓冲区接口的对象,就像您的情况一样。这在Python 2.7中得到修复,其中内置open
可以像3.x中的open
一样使用,而io.open
只是它的别名。
如果你需要二进制模式,使用open
,它在2.x和3.x中的行为相同,唯一的区别在于2.x它接受写入它不应该的对象(例如unicode
个对象)。如果您需要文字模式,请使用带有codecs.open
参数的io.open
或encoding
。两者都有3.x。
但请注意open
和io.open
是不可互换的,因为io
是Python 3的io
模块,而在Python 3中open
是与Python 2.6或更低版本中的open
非常不同。