首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Python3: gzip.open()和模式

Python3: gzip.open()和模式
EN

Stack Overflow用户
提问于 2017-02-02 21:57:35
回答 2查看 18.1K关注 0票数 12

https://docs.python.org/3/library/gzip.html

我正在考虑使用gzip.open(),我对mode的论点有点困惑:

模式参数可以是“r”、“rb”、“a”、“ab”、“w”、“wb”、“x”或“xb”表示二进制模式,或“rt”、“at”、“wt”或“xt”表示文本模式。默认情况是'rb‘。

那么,'w''wb'有什么区别呢?

文档声明它们都是二进制模式。

那么这是否意味着'w''wb'之间没有区别呢?

EN

Stack Overflow用户

发布于 2017-02-02 22:34:11

正如你所说的,正如@已经涵盖的那样

弗朗索瓦·法布雷回答。

我只是想展示一些代码,因为它很有趣。

让我们看一下python库中的gzip.py源代码,看看会发生什么。

gzip.open()可以在这里找到,https://github.com/python/cpython/blob/master/Lib/gzip.py和我在下面报告

代码语言:javascript
代码运行次数:0
运行
复制
def open(filename, mode="rb", compresslevel=9,
         encoding=None, errors=None, newline=None):
    """Open a gzip-compressed file in binary or text mode.
    The filename argument can be an actual filename (a str or bytes object), or
    an existing file object to read from or write to.
    The mode argument can be "r", "rb", "w", "wb", "x", "xb", "a" or "ab" for
    binary mode, or "rt", "wt", "xt" or "at" for text mode. The default mode is
    "rb", and the default compresslevel is 9.
    For binary mode, this function is equivalent to the GzipFile constructor:
    GzipFile(filename, mode, compresslevel). In this case, the encoding, errors
    and newline arguments must not be provided.
    For text mode, a GzipFile object is created, and wrapped in an
    io.TextIOWrapper instance with the specified encoding, error handling
    behavior, and line ending(s).
    """
    if "t" in mode:
        if "b" in mode:
            raise ValueError("Invalid mode: %r" % (mode,))
    else:
        if encoding is not None:
            raise ValueError("Argument 'encoding' not supported in binary mode")
        if errors is not None:
            raise ValueError("Argument 'errors' not supported in binary mode")
        if newline is not None:
            raise ValueError("Argument 'newline' not supported in binary mode")

    gz_mode = mode.replace("t", "")
    if isinstance(filename, (str, bytes, os.PathLike)):
        binary_file = GzipFile(filename, gz_mode, compresslevel)
    elif hasattr(filename, "read") or hasattr(filename, "write"):
        binary_file = GzipFile(None, gz_mode, compresslevel, filename)
    else:
        raise TypeError("filename must be a str or bytes object, or a file")

    if "t" in mode:
        return io.TextIOWrapper(binary_file, encoding, errors, newline)
    else:
        return binary_file  

我们注意到的事情很少:

  • 默认模式是rb,如您报告的文档所述
  • 要打开二进制文件,它不关心它是否是"r", "rb", "w", "wb"。 我们可以从以下几行看到这一点: gz_mode = mode.replace( "t“,"")如果isinstance(文件名,( str,字节,os.PathLike)):binary_file =GzipFile(文件名,gz_mode,压缩级别) elif (文件名,"read")或hasattr(文件名,”写“):binary_file = GzipFile(None,gz_mode,压缩级别,文件名)--binary_file(”文件名必须是str或字节对象,或文件“),如果”t“在模式中:返回io.TextIOWrapper(binary_file,编码,错误,换行符)其他:返回binary_file 基本上,二进制文件binary_file是构建的 现在调用类class GzipFile(_compression.BaseStream)来构建binary_file

在构造函数中,以下几行很重要:

代码语言:javascript
代码运行次数:0
运行
复制
 if mode and ('t' in mode or 'U' in mode):
        raise ValueError("Invalid mode: {!r}".format(mode))
    if mode and 'b' not in mode:
        mode += 'b'
    if fileobj is None:
        fileobj = self.myfileobj = builtins.open(filename, mode or 'rb')
    if filename is None:
        filename = getattr(fileobj, 'name', '')
        if not isinstance(filename, (str, bytes)):
            filename = ''
    else:
        filename = os.fspath(filename)
    if mode is None:
        mode = getattr(fileobj, 'mode', 'rb')

可以清楚地看到,如果'b'不在此模式中,则将添加

代码语言:javascript
代码运行次数:0
运行
复制
if mode and 'b' not in mode:
            mode += 'b'  

因此,正如前面所讨论的,这两种模式之间没有区别。

票数 4
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42013083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档