GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||
GeezerVison is showing python.github.io — io — 處理資料串流的核心工具 — Python 3.15.2 說明文件
|
抽象基底類別 (ABC) |
繼承 |
Stub 方法 |
Mixin 方法與屬性 |
|---|---|---|---|
|
|
||
|
繼承自 |
||
|
繼承自 |
||
|
繼承自 |
所有 I/O 類別的抽象基礎類別。
為許多方法提供了空的抽象實作,衍生類別可以選擇性地覆寫這些方法;預設的實作代表一個無法讀取、寫入或搜尋的檔案。
即使 IOBase 因為實作的簽名差異巨大而沒有宣告 read() 或 write() 方法,實作與用戶端應把這些方法視為介面的一部份。此外,當呼叫不被它們支援的操作時,可能會引發 ValueError (或 UnsupportedOperation)例外。
The basic type used for binary data read from or written to a file is
bytes. Other bytes-like objects are
accepted as method arguments too. Text I/O classes work with str data.
請注意,在一個已經關閉的串流上呼叫任何方法(即使只是查詢)都是未定義的。在這種情況下,實作可能會引發 ValueError 例外。
IOBase (and its subclasses) supports the iterator protocol, meaning
that an IOBase object can be iterated over yielding the lines in a
stream. Lines are defined slightly differently depending on whether the
stream is a binary stream (yielding bytes), or a text stream (yielding
character strings). See readline() below.
IOBase 也是個情境管理器,因此支援 with 陳述式。在這個例子中,file 會在 with 陳述式執行完畢後關閉——即使發生了異常。
with open('spam.txt', 'w') as file: file.write('Spam and eggs!')
IOBase 提供這些資料屬性與方法:
清除並關閉這個串流。若檔案已經關閉,則此方法沒有作用。一旦檔案被關閉,任何對檔案的操作(例如讀取或寫入)將引發 ValueError 異常。
為了方便起見,允許多次呼叫這個方法;然而,只有第一次呼叫會有效果。
如果串流已關閉,則為 True。
如果適用,清空串流的寫入緩衝區。對於唯讀和非阻塞串流,此操作不會執行任何操作。
如果串流是互動式的(即連接到終端機/tty 設備),則回傳 True。
從串流讀取並回傳一行。如果指定了 size,則最多讀取 size 個位元組。
對於二進位檔案,行結束符總是 b'\n';對於文字檔案,可以使用 open() 函式的 newline 引數來選擇識別的行結束符號。
從串流讀取並回傳一個含有一或多行的 list。可以指定 hint 來控制讀取的行數:如果到目前為止所有行的總大小(以位元組/字元計)超過 hint,則不會再讀取更多行。
hint 值為 0 或更小,以及 None,都被視為沒有提供 hint。
請注意,已經可以使用 for line in file: ... 在檔案物件上進行疊代,而不一定需要呼叫 file.readlines()。
將串流位置改變到給定的位元組 offset,此位置是相對於由 whence 指示的位置解釋的,並回傳新的絕對位置。whence 的值可為:
os.SEEK_SET 或 0 -- 串流的起點(預設值);offset 應為零或正數
os.SEEK_CUR 或 1 -- 目前串流位置;offset 可以是負數
os.SEEK_END 或 2 -- 串流的結尾;offset 通常是負數
在 3.1 版被加入: SEEK_* 常數。
在 3.3 版被加入: 某些作業系統可以支援額外的值,例如 os.SEEK_HOLE 或 os.SEEK_DATA。檔案的合法值取決於它是以文字模式還是二進位模式開啟。
如果串流支援隨機存取,則回傳 True。如果是 False,則 seek()、tell() 和 truncate() 會引發 OSError。
回傳目前串流的位置。
將串流的大小調整為指定的 size 位元組(如果沒有指定 size,則調整為目前位置)。目前串流位置不會改變。這種調整可以擴展或縮減目前檔案大小。在擴展的情況下,新檔案區域的內容取決於平台(在大多數系統上,額外的位元組會被填充為零)。回傳新的檔案大小。
在 3.5 版的變更: Windows 現在在擴展時會對檔案進行零填充 (zero-fill)。
如果串流支援寫入,則回傳 True。如果是 False,write() 和 truncate() 將會引發 OSError。
將一個包含每一行的 list 寫入串流。這不會新增行分隔符號,因此通常提供的每一行末尾都有一個行分隔符號。
原始二進位串流的基底類別。它繼承自 IOBase。
原始二進位串流通常提供對底層作業系統設備或 API 的低階存取,並不嘗試將其封裝在高階原語 (primitive) 中(這項功能在緩衝二進位串流和文字串流中的更高階層級完成,後面的頁面會有描述)。
RawIOBase 除了 IOBase 的方法外,還提供以下這些方法:
從物件中讀取最多 size 個位元組並回傳。方便起見,如果 size 未指定或為 -1,則回傳直到檔案結尾 (EOF) 的所有位元組。
嘗試只進行一次系統呼叫,但若被中斷且訊號處理器未引發例外,則會重試(請參閱 PEP 475 的原因說明)。這意味著如果作業系統呼叫回傳的位元組少於 size,則可能回傳少於 size 的位元組。
如果回傳了 0 位元組,且 size 不是 0,這表示檔案結尾 (end of file)。如果物件處於非阻塞模式且沒有可用的位元組,則回傳 None。
預設的實作會遵守 readall() 和 readinto() 的實作。
讀取並回傳串流中直到檔案結尾的所有位元組,必要時使用多次對串流的呼叫。
如果回傳了 0 個位元組,這表示檔案結尾 (end of file)。如果物件處於非阻塞模式且底層的 read() 回傳 None 表示沒有可用的位元組,則回傳 None。
讀取位元組到一個預先分配的、可寫的 bytes-like object b 當中,並回傳讀取的位元組數量。例如,b 可能是一個 bytearray。
如果回傳了 0 且 len(b) 不是 0,這表示檔案結尾 (end of file)。如果物件處於非阻塞模式且沒有可用的位元組,則回傳 None。
將給定的 bytes-like object (類位元組物件),b,寫入底層的原始串流,並回傳寫入的位元組大小。根據底層原始串流的具體情況,這可能少於 b 的位元組長度,尤其是當它處於非阻塞模式時。如果原始串流設置為非阻塞且無法立即寫入任何單一位元組,則回傳 None。呼叫者在此方法回傳後可以釋放或變更 b,因此實作應該只在方法呼叫期間存取 b。
警告
This function does not ensure all bytes are written or an exception is thrown. Callers may implement that behavior by checking the return value and, if it is less than the length of b, looping with additional write calls until all unwritten bytes are written. High-level I/O objects like 二進位 (Binary) I/O and 文字 I/O implement retry behavior.
支援某種緩衝的二進位串流的基底類別。它繼承自 IOBase。
與 RawIOBase 的主要差異在於,read()、readinto() 及 write() 方法將分別嘗試讀取所請求的盡可能多的輸入,或發出所有提供的資料。
In addition, if the underlying raw stream is in non-blocking mode, when the
system returns would block write() will raise BlockingIOError
with BlockingIOError.characters_written and read() will return
data read so far or None if no data is available.
此外,read() 方法不存在一個遵從 readinto() 的預設實作。
一個典型的 BufferedIOBase 實作不應該繼承自一個 RawIOBase 的實作,而是應該改用包裝的方式,像 BufferedWriter 和 BufferedReader 那樣的作法。
BufferedIOBase 除了提供或覆寫來自 IOBase 的資料屬性和方法以外,還包含了這些:
底層的原始串流(一個 RawIOBase 實例),BufferedIOBase 處理的對象。這不是 BufferedIOBase API 的一部分,且在某些實作可能不存在。
將底層的原始串流從緩衝區中分離出來,並回傳它。
在原始串流被分離後,緩衝區處於一個不可用的狀態。
某些緩衝區,如 BytesIO,沒有單一原始串流的概念可從此方法回傳。它們會引發 UnsupportedOperation。
在 3.1 版被加入.
讀取並回傳最多 size 個位元組。如果引數被省略、為 None 或為負值,將讀取盡可能最多的位元組。
Fewer bytes may be returned than requested. An empty bytes object
is returned if the stream is already at EOF. More than one read may be
made and calls may be retried if specific errors are encountered, see
os.read() and PEP 475 for more details. Less than size bytes
being returned does not imply that EOF is imminent.
When reading as much as possible the default implementation will use
raw.readall if available (which should implement
RawIOBase.readall()), otherwise will read in a loop until read
returns None, an empty bytes, or a non-retryable error. For
most streams this is to EOF, but for non-blocking streams more data may
become available.
備註
When the underlying raw stream is non-blocking, implementations may
either raise BlockingIOError or return None if no data is
available. io implementations return None.
Read and return up to size bytes, calling readinto()
which may retry if EINTR is encountered per
PEP 475. If size is -1 or not provided, the implementation will
choose an arbitrary value for size.
備註
When the underlying raw stream is non-blocking, implementations may
either raise BlockingIOError or return None if no data is
available. io implementations return None.
讀取位元組到一個預先分配的、可寫的 bytes-like object b 當中,並回傳讀取的位元組數量。例如,b 可能是一個 bytearray。
類似於 read(),除非後者是互動式的,否則可能會對底層原始串流發出多次讀取。
如果底層原始串流處於非阻塞模式,且目前沒有可用資料,則會引發 BlockingIOError。
讀取位元組到一個預先分配的、可寫的 bytes-like object b 中,最多呼叫一次底層原始串流的 read() (或 readinto())方法。此方法回傳讀取的位元組數量。
如果底層原始串流處於非阻塞模式,且目前沒有可用資料,則會引發 BlockingIOError。
在 3.5 版被加入.
寫入給定的 bytes-like object,b,並回傳寫入的位元組數量(總是等於 b 的長度,以位元組計,因為如果寫入失敗將會引發 OSError)。根據實際的實作,這些位元組可能會立即寫入底層串流,或出於性能和延遲的緣故而被留在緩衝區當中。
當處於非阻塞模式時,如果需要將資料寫入原始串流,但它無法接受所有資料而不阻塞,則會引發 BlockingIOError。
呼叫者可以在此方法回傳後釋放或變更 b,因此實作應該僅在方法呼叫期間存取 b。
A raw binary stream representing an OS-level file containing bytes data. It
inherits from RawIOBase and implements its low-level access design.
This means write() does not guarantee all bytes are written
and read() may read less bytes than requested even when more
bytes may be present in the underlying file. To get "write all" and
"read at least" behavior, use 二進位 (Binary) I/O.
name 可以是兩種事物之一:
代表將要打開的檔案路徑的一個字元串或 bytes 物件。在這種情況下,closefd 必須是 True (預設值),否則將引發錯誤。
an integer representing the number of an existing OS-level file descriptor
to which the resulting FileIO object will give access. When the
FileIO object is closed this fd will be closed as well, unless closefd
is set to False.
The mode can be 'r', 'w', 'x' or 'a' for reading
(default), writing, exclusive creation or appending. The file will be
created if it doesn't exist when opened for writing or appending; it will be
truncated when opened for writing. FileExistsError will be raised if
it already exists when opened for creating. Opening a file for creating
implies writing, so this mode behaves in a similar way to 'w'. Add a
'+' to the mode to allow simultaneous reading and writing.
A custom opener can be used by passing a callable as opener. The underlying
file descriptor for the file object is then obtained by calling opener with
(name, flags). opener must return an open file descriptor (passing
os.open as opener results in functionality similar to passing
None).
The newly created file is non-inheritable.
See the open() built-in function for examples on using the opener
parameter.
警告
FileIO is a low-level I/O object and members, such as
read() and write(), need to have their
return values checked explicitly in a retry loop to implement "write all"
and "read at least" behavior. High-level I/O objects 二進位 (Binary) I/O and
文字 I/O implement retry behavior.
在 3.3 版的變更: The opener parameter was added.
The 'x' mode was added.
在 3.4 版的變更: The file is now non-inheritable.
FileIO provides these data attributes in addition to those from
RawIOBase and IOBase:
The mode as given in the constructor.
The file name. This is the file descriptor of the file when no name is given in the constructor.
Buffered I/O streams provide a higher-level interface to an I/O device than raw I/O does.
A binary stream using an in-memory bytes buffer. It inherits from
BufferedIOBase. The buffer is discarded when the
close() method is called.
The optional argument initial_bytes is a bytes-like object that contains initial data.
Methods may be used from multiple threads without external locking in free-threaded builds.
BytesIO provides or overrides these methods in addition to those
from BufferedIOBase and IOBase:
Return a readable and writable view over the contents of the buffer without copying them. Also, mutating the view will transparently update the contents of the buffer:
>>> b = io.BytesIO(b"abcdef") >>> view = b.getbuffer() >>> view[2:4] = b"56" >>> b.getvalue() b'ab56ef'
備註
As long as the view exists, the BytesIO object cannot be
resized or closed.
在 3.2 版被加入.
In BytesIO, this is the same as read().
在 3.7 版的變更: The size argument is now optional.
In BytesIO, this is the same as readinto().
在 3.5 版被加入.
A buffered binary stream providing higher-level access to a readable, non
seekable RawIOBase raw binary stream. It inherits from
BufferedIOBase.
When reading data from this object, a larger amount of data may be requested from the underlying raw stream, and kept in an internal buffer. The buffered data can then be returned directly on subsequent reads.
The constructor creates a BufferedReader for the given readable
raw stream and buffer_size. If buffer_size is omitted,
DEFAULT_BUFFER_SIZE is used.
BufferedReader provides or overrides these methods in addition to
those from BufferedIOBase and IOBase:
Return bytes from the stream without advancing the position. The number of bytes returned may be less or more than requested. If the underlying raw stream is non-blocking and the operation would block, returns empty bytes.
In BufferedReader this is the same as io.BufferedIOBase.read()
In BufferedReader this is the same as io.BufferedIOBase.read1()
在 3.7 版的變更: The size argument is now optional.
A buffered binary stream providing higher-level access to a writeable, non
seekable RawIOBase raw binary stream. It inherits from
BufferedIOBase.
When writing to this object, data is normally placed into an internal
buffer. The buffer will be written out to the underlying RawIOBase
object under various conditions, including:
when the buffer gets too small for all pending data;
when flush() is called;
when a seek() is requested (for BufferedRandom objects);
when the BufferedWriter object is closed or destroyed.
The constructor creates a BufferedWriter for the given writeable
raw stream. If the buffer_size is not given, it defaults to
DEFAULT_BUFFER_SIZE.
BufferedWriter provides or overrides these methods in addition to
those from BufferedIOBase and IOBase:
Force bytes held in the buffer into the raw stream. A
BlockingIOError should be raised if the raw stream blocks.
Write the bytes-like object, b, and return the
number of bytes written. When in non-blocking mode, a
BlockingIOError with BlockingIOError.characters_written set
is raised if the buffer needs to be written out but the raw stream blocks.
A buffered binary stream implementing BufferedIOBase interfaces
providing higher-level access to a seekable RawIOBase raw binary
stream.
The constructor creates a reader and writer for a seekable raw stream, given
in the first argument. If the buffer_size is omitted it defaults to
DEFAULT_BUFFER_SIZE.
BufferedRandom is capable of anything BufferedReader or
BufferedWriter can do. In addition, seek() and
tell() are guaranteed to be implemented.
A buffered binary stream providing higher-level access to two non seekable
RawIOBase raw binary streams---one readable, the other writeable.
It inherits from BufferedIOBase.
reader and writer are RawIOBase objects that are readable and
writeable respectively. If the buffer_size is omitted it defaults to
DEFAULT_BUFFER_SIZE.
BufferedRWPair implements all of BufferedIOBase's methods
except for detach(), which raises
UnsupportedOperation.
警告
BufferedRWPair does not attempt to synchronize accesses to
its underlying raw streams. You should not pass it the same object
as reader and writer; use BufferedRandom instead.
Base class for text streams. This class provides a character and line based
interface to stream I/O. It inherits from IOBase.
TextIOBase provides or overrides these data attributes and
methods in addition to those from IOBase:
The name of the encoding used to decode the stream's bytes into strings, and to encode strings into bytes.
The error setting of the decoder or encoder.
A string, a tuple of strings, or None, indicating the newlines
translated so far. Depending on the implementation and the initial
constructor flags, this may not be available.
底層的二進位緩衝(一個 BufferedIOBase 或 RawIOBase 實例),為 TextIOBase 處理的對象。這不是 TextIOBase API 的一部分,且在某些實作可能不存在。
Separate the underlying binary buffer from the TextIOBase and
return it.
After the underlying buffer has been detached, the TextIOBase is
in an unusable state.
Some TextIOBase implementations, like StringIO, may not
have the concept of an underlying buffer and calling this method will
raise UnsupportedOperation.
在 3.1 版被加入.
Read and return at most size characters from the stream as a single
str. If size is negative or None, reads until EOF.
Read until newline or EOF and return a single str. If the stream is
already at EOF, an empty string is returned.
If size is specified, at most size characters will be read.
Change the stream position to the given offset. Behaviour depends on
the whence parameter. The default value for whence is
SEEK_SET.
SEEK_SET or 0: seek from the start of the stream
(the default); offset must either be a number returned by
TextIOBase.tell(), or zero. Any other offset value
produces undefined behaviour.
SEEK_CUR or 1: "seek" to the current position;
offset must be zero, which is a no-operation (all other values
are unsupported).
SEEK_END or 2: seek to the end of the stream;
offset must be zero (all other values are unsupported).
Return the new absolute position as an opaque number.
在 3.1 版被加入: SEEK_* 常數。
Return the current stream position as an opaque number. The number does not usually represent a number of bytes in the underlying binary storage.
Write the string s to the stream and return the number of characters written.
A buffered text stream providing higher-level access to a
BufferedIOBase buffered binary stream. It inherits from
TextIOBase.
encoding gives the name of the encoding that the stream will be decoded or
encoded with. This defaults to UTF-8; if UTF-8 Mode is
disabled, it defaults to locale.getencoding().
encoding="locale" can be used to specify the current locale's encoding
explicitly. See Text encoding for more information.
errors is an optional string that specifies how encoding and decoding
errors are to be handled. Pass 'strict' to raise a ValueError
exception if there is an encoding error (the default of None has the same
effect), or pass 'ignore' to ignore errors. (Note that ignoring encoding
errors can lead to data loss.) 'replace' causes a replacement marker
(such as '?') to be inserted where there is malformed data.
'backslashreplace' causes malformed data to be replaced by a
backslashed escape sequence. When writing, 'xmlcharrefreplace'
(replace with the appropriate XML character reference) or 'namereplace'
(replace with \N{...} escape sequences) can be used. Any other error
handling name that has been registered with
codecs.register_error() is also valid.
newline controls how line endings are handled. It can be None,
'', '\n', '\r', and '\r\n'. It works as follows:
When reading input from the stream, if newline is None,
universal newlines mode is enabled. Lines in the input can end in
'\n', '\r', or '\r\n', and these are translated into '\n'
before being returned to the caller. If newline is '', universal
newlines mode is enabled, but line endings are returned to the caller
untranslated. If newline has any of the other legal values, input lines
are only terminated by the given string, and the line ending is returned to
the caller untranslated.
When writing output to the stream, if newline is None, any '\n'
characters written are translated to the system default line separator,
os.linesep. If newline is '' or '\n', no translation
takes place. If newline is any of the other legal values, any '\n'
characters written are translated to the given string.
If line_buffering is True, flush() is implied when a call to
write contains a newline character or a carriage return.
If write_through is True, calls to write() are guaranteed
not to be buffered: any data written on the TextIOWrapper
object is immediately handled to its underlying binary buffer.
在 3.3 版的變更: The write_through argument has been added.
在 3.3 版的變更: The default encoding is now locale.getpreferredencoding(False)
instead of locale.getpreferredencoding(). Don't change temporary the
locale encoding using locale.setlocale(), use the current locale
encoding instead of the user preferred encoding.
在 3.10 版的變更: The encoding argument now supports the "locale" dummy encoding name.
備註
When the underlying raw stream is non-blocking, a BlockingIOError
may be raised if a read operation cannot be completed immediately.
TextIOWrapper provides these data attributes and methods in
addition to those from TextIOBase and IOBase:
Whether line buffering is enabled.
Whether writes are passed immediately to the underlying binary buffer.
在 3.7 版被加入.
Reconfigure this text stream using new settings for encoding, errors, newline, line_buffering and write_through.
Parameters not specified keep current settings, except
errors='strict' is used when encoding is specified but
errors is not specified.
It is not possible to change the encoding or newline if some data has already been read from the stream. On the other hand, changing encoding after write is possible.
This method does an implicit stream flush before setting the new parameters.
在 3.7 版被加入.
在 3.11 版的變更: The method supports encoding="locale" option.
Set the stream position.
Return the new stream position as an int.
Four operations are supported, given by the following argument combinations:
seek(0, SEEK_SET): Rewind to the start of the stream.
seek(cookie, SEEK_SET): Restore a previous position;
cookie must be a number returned by tell().
seek(0, SEEK_END): Fast-forward to the end of the stream.
seek(0, SEEK_CUR): Leave the current stream position unchanged.
Any other argument combinations are invalid, and may raise exceptions.
也參考
A text stream using an in-memory text buffer. It inherits from
TextIOBase.
The text buffer is discarded when the close() method is
called.
The initial value of the buffer can be set by providing initial_value.
If newline translation is enabled, newlines will be encoded as if by
write(). The stream is positioned at the start of the
buffer which emulates opening an existing file in a w+ mode, making it
ready for an immediate write from the beginning or for a write that
would overwrite the initial value. To emulate opening a file in an a+
mode ready for appending, use f.seek(0, io.SEEK_END) to reposition the
stream at the end of the buffer.
The newline argument works like that of TextIOWrapper,
except that when writing output to the stream, if newline is None,
newlines are written as \n on all platforms.
StringIO provides this method in addition to those from
TextIOBase and IOBase:
Return a str containing the entire contents of the buffer.
Newlines are decoded as if by read(), although
the stream position is not changed.
使用範例:
import io output = io.StringIO() output.write('First line.\n') print('Second line.', file=output) # Retrieve file contents -- this will be # 'First line.\nSecond line.\n' contents = output.getvalue() # Close object and discard memory buffer -- # .getvalue() will now raise an exception. output.close()
A helper codec that decodes newlines for universal newlines mode.
It inherits from codecs.IncrementalDecoder.
The following protocols can be used for annotating function and method
arguments for simple stream reading or writing operations. They are decorated
with @typing.runtime_checkable.
Generic protocol for reading from a file or other input stream. T will
usually be str or bytes, but can be any type that is
read from the stream.
在 3.14 版被加入.
Read data from the input stream and return it. If size is specified, it should be an integer, and at most size items (bytes/characters) will be read.
例如:
def read_it(reader: Reader[str]): data = reader.read(11) assert isinstance(data, str)
Generic protocol for writing to a file or other output stream. T will
usually be str or bytes, but can be any type that can be
written to the stream.
在 3.14 版被加入.
Write data to the output stream and return the number of items (bytes/characters) written.
例如:
def write_binary(writer: Writer[bytes]): writer.write(b"Hello world!\n")
See ABCs and Protocols for working with I/O for other I/O related protocols and classes that can be used for static type checking.
This section discusses the performance of the provided concrete I/O implementations.
By reading and writing only large chunks of data even when the user asks for a single byte, buffered I/O hides any inefficiency in calling and executing the operating system's unbuffered I/O routines. The gain depends on the OS and the kind of I/O which is performed. For example, on some modern OSes such as Linux, unbuffered disk I/O can be as fast as buffered I/O. The bottom line, however, is that buffered I/O offers predictable performance regardless of the platform and the backing device. Therefore, it is almost always preferable to use buffered I/O rather than unbuffered I/O for binary data.
Text I/O over a binary storage (such as a file) is significantly slower than
binary I/O over the same storage, because it requires conversions between
unicode and binary data using a character codec. This can become noticeable
handling huge amounts of text data like large log files. Also,
tell() and seek() are both quite slow
due to the reconstruction algorithm used.
StringIO, however, is a native in-memory unicode container and will
exhibit similar speed to BytesIO.
FileIO objects are thread-safe to the extent that the operating system
calls (such as read(2) under Unix) they wrap are thread-safe too.
Binary buffered objects (instances of BufferedReader,
BufferedWriter, BufferedRandom and BufferedRWPair)
protect their internal structures using a lock; it is therefore safe to call
them from multiple threads at once.
TextIOWrapper 物件不是執行緒安全的。
Binary buffered objects (instances of BufferedReader,
BufferedWriter, BufferedRandom and BufferedRWPair)
are not reentrant. While reentrant calls will not happen in normal situations,
they can arise from doing I/O in a signal handler. If a thread tries to
re-enter a buffered object which it is already accessing, a RuntimeError
is raised. Note this doesn't prohibit a different thread from entering the
buffered object.
The above implicitly extends to text files, since the open() function
will wrap a buffered object inside a TextIOWrapper. This includes
standard streams and therefore affects the built-in print() function as
well.