I've seen this syntax while dealing with the Python requests library:
body = { file_name: open(file_path, 'rb') }
I wonder if this closes the file as I've seen it written like this multiple times.
I've seen this syntax while dealing with the Python requests library:
body = { file_name: open(file_path, 'rb') }
I wonder if this closes the file as I've seen it written like this multiple times.
Re-posting my comment as accepted answer:
It basically does: When the file object returned by open()
has no more references to it the file will be closed. In this case a reference is held by the dictionary, but likewise when there are no references to the dictionary remaining it will also drop the reference to the file when it goes out of scope. This can potentially lead to bugs, with file handles being left open. Python 3 will warn about this if you run with python -Wall
. For read-only files it's mostly harmless since there's no data to flush to disk. But I still would avoid this.
For example:
$ python3 -Wall
Python 3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> {'f': open('.bashrc')}
{'f': <_io.TextIOWrapper name='.bashrc' mode='r' encoding='UTF-8'>}
>>> exit()
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='.bashrc' mode='r' encoding='UTF-8'>
Actually you don't even need the dict
for this:
$ python3 -Wall
Python 3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> open('.bashrc')
<_io.TextIOWrapper name='.bashrc' mode='r' encoding='UTF-8'>
>>> exit()
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='.bashrc' mode='r' encoding='UTF-8'>
this is because in the last case, the last returned value in the REPL is stored in the special variable _
.
In fact, this ResourceWarning
will be raised any time the file object's __del__
is called before it's been explicitly closed:
$ python3 -Wall
Python 3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('.bashrc')
>>> del f
__main__:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='.bashrc' mode='r' encoding='UTF-8'>
This is only a warning (and disabled by default) since it's not generally a serious problem, as the file will still be closed. But it could indicate a bug, but so it's good to enable this warning when debugging file I/O issues, and also to open files using the with
statement as general good practice:
>>> with open(file_path, 'rb') as fobj:
... body = { file_name: fobj }
... # send request, etc...