【问题标题】:Prefer BytesIO or bytes for internal interface in Python?Python 中的内部接口更喜欢 BytesIO 还是 bytes?
【发布时间】:2015-04-19 20:22:18
【问题描述】:

我正在尝试确定在我的代码中使用的最佳内部接口,特别是围绕如何处理文件内容。实际上,文件内容只是二进制数据,因此字节足以表示它们。

我将文件存储在不同的远程位置,因此有几个不同的类用于读写。我正在尝试找出用于我的功能的最佳界面。最初我使用的是文件路径,但这不是最理想的,因为这意味着磁盘总是被使用(这意味着很多笨拙的临时文件)。

代码中有几个区域具有相同的要求,并且会直接使用从该接口返回的任何内容。因此,我选择的任何抽象都会涉及到相当多的代码。

使用 BytesIO 与字节的各种权衡是什么?

def put_file(location, contents_as_bytes):
def put_file(location, contents_as_fp):
def get_file_contents(location):
def get_file_contents(location, fp):

我发现使用 File-Like 接口(BytesIO 等)需要一些管理开销,例如 seek(0) 等。这就提出了如下问题:

  • 是在开始之前还是在完成之后seek 更好?
  • 您是从seek 开始还是从文件所在的位置开始操作?
  • 您是否应该tell() 保持位置?
  • 查看shutil.copyfileobj 之类的内容不会进行任何搜索

我发现使用类似文件的接口的一个优点是它允许在检索数据时传入 fp 以写入。这似乎提供了很大的灵活性。

def get_file_contents(location, write_into=None):
    if not write_into:
        write_into = io.BytesIO()

    # get the contents and put it into write_into

    return write_into

get_file_contents('blah', file_on_disk)
get_file_contents('blah', gzip_file)
get_file_contents('blah', temp_file)
get_file_contents('blah', bytes_io)
new_bytes_io = get_file_contents('blah')
# etc

在 python 中设计接口时,是否有充分的理由更喜欢 BytesIO 而不是仅使用固定字节?

【问题讨论】:

    标签: python python-3.x file-handling bytesio


    【解决方案1】:

    io.BytesIO 对象的好处是它们实现了一个通用接口(通常称为“类文件”对象)。 BytesIO 对象有一个内部指针(其位置由tell() 返回),每次调用read(n) 指针都会前进n 字节。例如。

    import io
    
    buf = io.BytesIO(b'Hello world!')
    buf.read(1) # Returns b'H'
    
    buf.tell()  # Returns 1
    buf.read(1) # Returns b'e'
    
    buf.tell() # Returns 2
    
    # Set the pointer to 0.
    buf.seek(0)
    buf.read() # This will return b'H', like the first call.
    

    在您的用例中,bytes 对象和io.BytesIO 对象可能都不是最佳解决方案。他们会将您文件的完整内容读入内存。

    相反,您可以查看tempfile.TemporaryFile (https://docs.python.org/3/library/tempfile.html)。

    【讨论】:

    • 感谢您的意见。我最终使用了字节和类似文件的对象的组合。关于 tempfile 的好处 - 使用类似文件的对象可以在需要时灵活地使用 tempfile,这可以为某些用例提供更好的时间/空间权衡。
    • 最后一个buf.read() 将返回整个字符串。如果您省略 size 参数或使用负值,它将一直读取到 EOF。我想你的意思是buf.read(1)
    猜你喜欢
    • 2015-06-13
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多