Python 3:gzip.open()和模式

时间:2017-02-02 21:57:35

标签: python python-3.x gzip mode

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'之间没有区别?

2 个答案:

答案 0 :(得分:7)

这意味着r默认为rb,如果您需要文字,则必须使用rt指定。

(与open表示r表示rt,而不是rbimport { Input } from '@angular/core'; export class app { @Input() chartLabelObject:string[]; } 行为相反。

答案 1 :(得分:4)

正如你所说的那样,@

已经涵盖了

Jean-FrançoisFabre回答。
我只是想展示一些代码,因为它很有趣 让我们看看python库中的gzip.py源代码,看看实际发生了什么。
可以在https://github.com/python/cpython/blob/master/Lib/gzip.py找到gzip.open(),我在下面报告

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", "")
    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
    

    基本上二进制文件binary_file是否已经构建,还有另外一个b,因为gz_mode此时可以b。{
    1}} 现在调用类class GzipFile(_compression.BaseStream)来构建binary_file

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

 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',则会添加

if mode and 'b' not in mode:
            mode += 'b'  

因此,已经讨论过的两种模式之间没有区别。