overwrite file reference variable in with statement
-
21-06-2021 - |
Question
I was curious if this causes any bad behaviors. I ran a test case and got no errors so I assume its OK (although probably not good practice). Just wanted to know how python deals with the issue I assumed should have existed?
with open("somefile.txt","r") as fileinfo:
fileinfo = fileinfo.readlines()
print fileinfo
I thought overwritting "fileinfo" would cause issues exiting the with statement (raise some error about not being able to .close() a list). Does the with statement retain a local copy of the file reference? Thanks!
Solution
Of course Python retains an internal reference to the object used in the with
statement. Otherwise how would it work when you don't use the as
clause?
OTHER TIPS
A with statement does indeed store a local reference to the file object (although I am not positive exactly what is stored in self.gen)
Looked into the topic, specifically researching the context manager and found this which gives slightly more detail for those interested.
class GeneratorContextManager(object):
def __init__(self, gen):
# Store local copy of "file reference"
self.gen = gen
def __enter__(self):
try:
return self.gen.next()
except StopIteration:
raise RuntimeError("generator didn't yield")
def __exit__(self, type, value, traceback):
if type is None:
try:
self.gen.next()
except StopIteration:
return
else:
raise RuntimeError("generator didn't stop")
else:
try:
self.gen.throw(type, value, traceback)
raise RuntimeError("generator didn't stop after throw()")
except StopIteration:
return True
except:
# only re-raise if it's *not* the exception that was
# passed to throw(), because __exit__() must not raise
# an exception unless __exit__() itself failed. But
# throw() has to raise the exception to signal
# propagation, so this fixes the impedance mismatch
# between the throw() protocol and the __exit__()
# protocol.
#
if sys.exc_info()[1] is not value:
raise
def contextmanager(func):
def helper(*args, **kwds):
return GeneratorContextManager(func(*args, **kwds))
return helper