I generally like to use the with open(...) as file:
idiom for opening files because it avoids failing to close a file, improves code readability, and improves exception handling. However, I have seen other people's code use one-liners to open and read/write a file without saving the TextIOWrapper
object:
# Read a file
contents = open('the_file.txt').read()
# Write to a file
open('the_file.txt', 'w').write('This is the thing.')
# Write an empty file
open('empty_file.txt', 'w')
These idioms are appealing because of their simplicity, but I want to understand what python does with those file objects.
I tried using the dis
module to inspect the bytecode, but I'm not sure how to read the output:
def myfunc():
open('test.txt', 'w')
dis.dis(myfunc)
2 0 LOAD_GLOBAL 0 (open) 2 LOAD_CONST 1 ('test.txt') 4 LOAD_CONST 2 ('w') 6 CALL_FUNCTION 2 8 POP_TOP 10 LOAD_CONST 0 (None) 12 RETURN_VALUE
def withfunc():
with open('test.txt', 'w') as f:
pass
dis.dis(withfunc)
2 0 LOAD_GLOBAL 0 (open) 2 LOAD_CONST 1 ('test.txt') 4 LOAD_CONST 2 ('w') 6 CALL_FUNCTION 2 8 SETUP_WITH 6 (to 16) 10 STORE_FAST 0 (f) 3 12 POP_BLOCK 14 LOAD_CONST 0 (None) >> 16 WITH_CLEANUP_START 18 WITH_CLEANUP_FINISH 20 END_FINALLY 22 LOAD_CONST 0 (None) 24 RETURN_VALUE
def savefunc():
f = open('test.txt', 'w')
f.close()
dis.dis(savefunc)
2 0 LOAD_GLOBAL 0 (open) 2 LOAD_CONST 1 ('test.txt') 4 LOAD_CONST 2 ('w') 6 CALL_FUNCTION 2 8 STORE_FAST 0 (f) 3 10 LOAD_FAST 0 (f) 12 LOAD_ATTR 1 (close) 14 CALL_FUNCTION 0 16 POP_TOP 18 LOAD_CONST 0 (None) 20 RETURN_VALUE
I have two questions:
- What happens under the hood when you use
open
without saving the TextIOWrapper object (especially regarding whether they are properly closed) - Are there reasons to NOT use the one-liners?