“with” syntax for opening files with two functions

  • A+

Let's say I want to open a text file for reading using the following syntax:

with open(fname,'r') as f:     # do something     pass 

But if I detect that it ends with .gz, I would call gzip.open().

if fname.endswith('.gz'):     with gzip.open(fname,'rt') as f:             # do something             pass else:     with open(fname,'r') as f:             # do something             pass 

If "do something" part is long and not convenient to write in a function (e.g. it would create a nested function, which cannot be serialized), what is the shortest way to call with either gzip.open or open based on the return of fname.endswith('.gz')?


You can bind either context manager to the same name and choose early:

if fname.endswith('.gz'):     context = gzip.open(fname,'rt') else:     context = open(fname,'r')  with context as f:     # do the same thing in either case 

This allows for some nice patterns, for instance if the input is possibly an opened file handle then you could use contextlib.nullcontext to get a no-op in the with block for the given case.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: