代码之家  ›  专栏  ›  技术社区  ›  Kriattiffer

Python 2.7中的Open()和codecs.Open()的行为有着奇怪的不同

  •  8
  • Kriattiffer  · 技术社区  · 13 年前

    我有一个文本文件,第一行是unicode字符,其他所有行都是ASCII。 我试着将第一行作为一个变量读取,将所有其他行作为另一个变量。但是,当我使用以下代码时:

    # -*- coding: utf-8 -*-
    import codecs
    import os
    filename = '1.txt'
    f = codecs.open(filename, 'r3', encoding='utf-8')
    print f
    names_f = f.readline().split(' ')
    data_f = f.readlines()
    print len(names_f)
    print len(data_f)
    f.close()
    print 'And now for something completely differerent:'
    g = open(filename, 'r')
    names_g = g.readline().split(' ')
    print g
    data_g = g.readlines()
    print len(names_g)
    print len(data_g)
    g.close()
    

    我得到以下输出:

    <open file '1.txt', mode 'rb' at 0x01235230>
    28
    
    7
    
    And now for something completely differerent:
    
    <open file '1.txt', mode 'r' at 0x017875A0>
    
    28
    
    77
    

    如果我不使用readlines(),整个文件都会读取,而不仅仅是codecs.open()和open()的前7行。

    为什么会发生这样的事情? 为什么codecs.open()以二进制模式读取文件,尽管添加了“r”参数?

    Upd:这是原始文件: http://www1.datafilehost.com/d/0792d687

    1 回复  |  直到 12 年前
        1
  •  17
  •   Martijn Pieters    12 年前

    因为你曾经 .readline() 第一 这个 codecs.open() 文件已填充行缓冲区;对的后续调用 .readlines() 退货 只有 缓冲线路。

    如果你打电话 .readlines() 再一次 ,返回其余行:

    >>> f = codecs.open(filename, 'r3', encoding='utf-8')
    >>> line = f.readline()
    >>> len(f.readlines())
    7
    >>> len(f.readlines())
    71
    

    解决办法是不要混在一起 .redline() .readlines() :

    f = codecs.open(filename, 'r3', encoding='utf-8')
    data_f = f.readlines()
    names_f = data_f.pop(0).split(' ')  # take the first line.
    

    这种行为真是个bug;Python开发人员已经意识到了这一点,请参阅 issue 8260 .

    另一种选择是使用 io.open() 而不是 编解码器.open() ; 这个 io 库是Python 3用来实现内置的 open() 功能,并且比 codecs 单元