I've got a working program that calls an API for each item of a list (say, a book) to get back metadata about the book. It stores the book : metadata in dict for use. This causes the user to wait during the metadata gathering, so avoid excess calls I am persisting the dict to CSV and loading it before making aforementioned API calls to ensure I only get responses when necessary.
However, when I introduce context managers to read the persisted dict, and then do the call-if-not-there logic into a function ("gatherfiles()"), it is no longer accessible to a third function.
I can see the dict is returned by gatherfiles() when I call in in a main function, but when I make the third function call (to "pickabook()") I get a keyerror and I see an empty dictionary.
I've put a redacted version of the code below. My guess is that somehow the context manager has changed the scoping (so it's treating one shimdict as global and one as local), but that doesn't seem right given what I can read online. So any thoughts here that aren't ugly?
shimdict = {}
def pickabook(book=None):
print(shimdict, "<-this is {}. why?!?")
picked = shimdict.pop(book)
def gatherfiles(directory):
with open('test.csv', 'rb') as f:
reader = csv.reader(f,)
shimdict = dict((rows[0],rows[1]) for rows in reader)
with open('test.csv', 'a+b') as f:
w = csv.writer(f)
ff = os.listdir(directory)
for f in ff:
if f.rsplit('.', 1)[1].lower() in [....]:
filename = os.path.join(directory, f)
if filename in shimdict.keys():
print("already here")
else:
print("make the api call, then write the value to dict & then csv")
shimdict[filename] = (returnedvalue)
w.writerow([filename, (returnedvalue)])
return shimdict
def main():
shimdict = gatherfiles(directory)
print(shimdict, "<-dictionary works")
while 1:
print(shimdict, "<-dictionary works")
current = pickabook(bookname)
---- edit below ---- I don't think I posed my question explicitly enough. I am able to access the dict "shimdict" in "pickabook()" if the context managers are removed i.e. I use this code:
def gatherfiles(directory):
ff = os.listdir(directory)
for f in ff:
if f.rsplit('.', 1)[1].lower() in [....]:
filename = os.path.join(directory, f)
shimdict[filename] = (returnedvalue)
return shimdict
So i completely understand that I can use global or pass the local dict to the function to fix this, but I want to know why adding the context manager changes the behavior.