Skip to main content
deleted 483 characters in body
Source Link
Sraw
  • 20.6k
  • 11
  • 61
  • 93

with open(path) as f: is a syntax sugar to automatically "close" object f, but it doesn't mean you have to I think use it. A simple f = open(path) and f.close()a helper is still OK.

So why notbetter:

from contextlib import ExitStack, contextmanager class Foo: def __init__(self, in_file_namei, out_file_nameo): self.i = open(in_file_name, 'r')i self.o = openo @contextmanager def multiopen(out_file_namei, 'w'o)  : defwith __enter__ExitStack(self):  as stack:  return self  i def= __exit__stack.enter_context(*excopen(i):) self.io = stack.closeenter_context(open(o)) self.o.closeyield Foo(i, o) 

There are so many similar usages. For example, in requests, __exit__ aThe usage is close to native Sessionopen instance will execute code closing underlying adapters(connection pool). Related code:

class Session(SessionRedirectMixin): # ... omitted defwith __exit__multiopen(selfi_name, *args):  self.close() def close(selfo_name):  """Closes all adapters and as such the session"""  for v in self.adapters.values()foo:   v.close()pass 

with open(path) as f: is a syntax sugar to automatically "close" object f, but it doesn't mean you have to use it. A simple f = open(path) and f.close() is still OK.

So why not:

class Foo: def __init__(self, in_file_name, out_file_name): self.i = open(in_file_name, 'r') self.o = open(out_file_name, 'w')   def __enter__(self):  return self  def __exit__(*exc): self.i.close() self.o.close() 

There are so many similar usages. For example, in requests, __exit__ a Session instance will execute code closing underlying adapters(connection pool). Related code:

class Session(SessionRedirectMixin): # ... omitted def __exit__(self, *args):  self.close() def close(self):  """Closes all adapters and as such the session"""  for v in self.adapters.values():   v.close() 

I think use a helper is better:

from contextlib import ExitStack, contextmanager class Foo: def __init__(self, i, o): self.i = i self.o = o @contextmanager def multiopen(i, o): with ExitStack() as stack:  i = stack.enter_context(open(i)) o = stack.enter_context(open(o)) yield Foo(i, o) 

The usage is close to native open:

with multiopen(i_name, o_name) as foo: pass 
Source Link
Sraw
  • 20.6k
  • 11
  • 61
  • 93

with open(path) as f: is a syntax sugar to automatically "close" object f, but it doesn't mean you have to use it. A simple f = open(path) and f.close() is still OK.

So why not:

class Foo: def __init__(self, in_file_name, out_file_name): self.i = open(in_file_name, 'r') self.o = open(out_file_name, 'w') def __enter__(self): return self def __exit__(*exc): self.i.close() self.o.close() 

There are so many similar usages. For example, in requests, __exit__ a Session instance will execute code closing underlying adapters(connection pool). Related code:

class Session(SessionRedirectMixin): # ... omitted def __exit__(self, *args): self.close() def close(self): """Closes all adapters and as such the session""" for v in self.adapters.values(): v.close()