today while programming I found myself managing a resource (ssh connection) inside a generator function, something similar to the following:
def _yield_fname(host_address, usr, pwd, datapath):
with paramiko.SSHClient() as ssh_client:
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(host, username=usr, password=pwd)
stdin, stdout, stderr = ssh_client.exec_command(
'find . -type d -maxdepth 1 -printf "%fn"'
)
for line in stdout:
yield fname
def get_foos():
foos= []
for fname in self._yield_fname(self.FOO_PATH):
foos.append(Foo.from_fname(fname))
return foos
def get_bars():
bars= []
for fname in self._yield_fname(self.FOO_PATH):
bars.append(Bar.from_fname(fname))
return bars
is it bad practice to manage a resource inside a generator function in this way?
In my case I plan to always consume yield_fname
‘s generator from start to finish, so that the connection is always closed. Should I worry about someone (e.g. future me) using the generator without fully consuming it and leaving the connection open? is there a way to prevent that?
(as a side note, here I decided to use a generator function because I wanted to avoid looping through the list of filenames two or more times)