簡體   English   中英

Python 3:gzip.open()和模式

[英]Python 3: gzip.open() and modes

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'之間沒有區別?

這意味着r默認為rb ,如果需要文本,則必須使用rt指定它。

(與open行為相反,其中r表示rt ,而不是rb

正如你所說和@已經涵蓋的那樣

Jean-FrançoisFabre的回答。
我只是想展示一些代碼,因為它很有趣。
讓我們看一下python庫中的gzip.py源代碼,看看有效的情況。
gzip.open()可以在這里找到https://github.com/python/cpython/blob/master/Lib/gzip.py ,我在下面報告

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或者沒有。
    現在調用類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'  

因此,已經討論過的兩種模式之間沒有區別。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM