bug或功能:open和io.open不可互换

时间:2011-02-04 10:12:15

标签: python api file-io

我一直认为openio.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中测试

1 个答案:

答案 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.openencoding。两者都有3.x。

但请注意openio.open是不可互换的,因为io是Python 3的io模块,而在Python 3中open是与Python 2.6或更低版本中的open非常不同。

http://docs.python.org/library/io.html