0

Just started working with Python today, so if I'm doing something crazy here please let me know. I have been working to simplify a block of code so that I can more easily reuse it. My goal would be to just update one set of variables during each reuse. The last working code I had is this:

class_a='amstaff'
class_b='beagle'
class_c='doberman'
class_d='germanshepherd'
class_e='rottweiler'

with open(file_path +class_a+'.zip', 'rb') as class_a, open(file_path +class_b+'.zip', 'rb') as class_b, open(file_path +class_c+'.zip', 'rb') as class_c, open(file_path +class_d+'.zip', 'rb') as class_d, open(file_path +class_e+'.zip', 'rb') as class_e:

    model = visual_recognition.create_classifier(
        classifier_name,
        amstaff_positive_examples=class_a,
        beagle_positive_examples=class_b,
        doberman_positive_examples=class_c,
        germanshepherd_positive_examples=class_d,
        rottweiler_positive_examples=class_e)
print(json.dumps(model, indent=2))

This saves me a ton of time from my original code but still requires a fair bit of editing. So I was thinking I might be able to use a for loop but I got stuck about halfway through. Here's what I have so far, but I am stumped on how to proceed from here.

classes=["amstaff", "beagle", "doberman", "germanshepherd", "rottweiler"]

for x in classes:
    with open(file_path +x+'.zip', 'rb') as x:

model = visual_recognition.create_classifier(
    classifier_name,
    amstaff_positive_examples=class_a,
    beagle_positive_examples=class_b,
    doberman_positive_examples=class_c,
    germanshepherd_positive_examples=class_d,
    rottweiler_positive_examples=class_e)
print(json.dumps(model, indent=2))
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
Joe Cambareri
  • 115
  • 2
  • 13
  • 1
    is your code posted here has same indentation as the code in your system? – Arghya Saha Aug 22 '18 at 05:54
  • 1
    This is actually trickier than you might think. To really do this, you would have to implement a sort of "meta-context-manager" to handle the other context-managers you want to enter and exit appropriately [`contextlib.ExitStack`](https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack). Indeed, the example in the docs is a list of file-names to open. Just follow the example. – juanpa.arrivillaga Aug 22 '18 at 05:59
  • 1
    Alternatively, you could just *not* use context managers, but you'd want to wrap up everything the old way, with a `try-except-finally`, taking care to close all possibly opened files in the finally – juanpa.arrivillaga Aug 22 '18 at 06:02

1 Answers1

1

If you are using python 3.3+, there is ExitStack which you could use to manage all the context managers. All opened files will automatically be closed at the end of the with statement.

classes=["amstaff", "beagle", "doberman", "germanshepherd", "rottweiler"]
with ExitStack() as stack:
    files = [stack.enter_context(open(fname)) for fname in classes]

And files will have all the handles to open files that you could use to create your model.

Sushant
  • 3,499
  • 3
  • 17
  • 34