修复AttributeError:' file'对象没有属性'缓冲区' (Python3)

时间:2017-12-10 17:31:15

标签: linux python-3.x python-2.7 type-conversion

Ubuntu上的Python 2.7。我试过为Python3运行小python脚本(文件转换器),得到错误:

$ python uboot_mdb_to_image.py < input.txt > output.bin
Traceback (most recent call last):
  File "uboot_mdb_to_image.py", line 29, in <module>
    ascii_stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='ascii', errors='strict')
AttributeError: 'file' object has no attribute 'buffer'

我怀疑它是由python 3和python 2之间的语法差异引起的,这里是脚本本身:

#!/usr/bin/env python3

import sys
import io

BYTES_IN_LINE = 0x10 # Number of bytes to expect in each line

c_addr = None
hex_to_ch = {}

ascii_stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='ascii', errors='strict')

for line in ascii_stdin:
    line = line[:-1] # Strip the linefeed (we can't strip all white
                     # space here, think of a line of 0x20s)
    data, ascii_data = line.split("    ", maxsplit = 1)
    straddr, strdata = data.split(maxsplit = 1)
    addr = int.from_bytes(bytes.fromhex(straddr[:-1]), byteorder = 'big')
    if c_addr != addr - BYTES_IN_LINE:
        if c_addr:
            sys.exit("Unexpected c_addr in line: '%s'" % line)
    c_addr = addr
    data = bytes.fromhex(strdata)
    if len(data) != BYTES_IN_LINE:
        sys.exit("Unexpected number of bytes in line: '%s'" % line)
    # Verify that the mapping from hex data to ASCII is consistent (sanity check for transmission errors)
    for b, c in zip(data, ascii_data):
        try:
            if hex_to_ch[b] != c:
                sys.exit("Inconsistency between hex data and ASCII data in line (or the lines before): '%s'" % line)
        except KeyError:
            hex_to_ch[b] = c
    sys.stdout.buffer.write(data)

有人可以建议如何解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

这是一个古老的问题,但是由于我遇到了类似的问题,因此在搜索错误时首先出现了该问题...

是的,这是由Python 3和2之间的差异引起的。在Python 3中,sys.stdin被包装在io.TextIOWrapper中。在Python 2中,它是一个file对象,没有buffer属性。 stderrstdout也是如此。

在这种情况下,可以使用codecs标准库在Python 2中实现相同的功能:

ascii_stdin = codecs.getreader("ascii")(sys.stdin, errors="strict")

但是,此代码段提供了codecs.StreamReader而不是io.TextIOWrapper的实例,因此在其他情况下可能不适合。而且,不幸的是,将Python 2 stdin封装在io.TextIOWrapper中并非易事-有关更多讨论,请参见Wrap an open stream with io.TextIOWrapper

有问题的脚本具有更多的Python 2不兼容性。与有问题的问题相关,sys.stdout没有buffer属性,因此最后一行应该是

sys.stdout.write(data)

我能发现的其他东西:

  • str.split没有maxsplit参数。请改用line.split(" ")[:2]
  • int没有from_bytes属性。但是int(straddr[:-1].encode('hex'), 16)似乎是等效的。
  • bytes类型仅适用于Python 3。在Python 2中,它是str的别名。