Search code examples
pythonfunctionglobal-variables

UnboundLocalError on local variable with two def() functions


I am receiving the error:

UnboundLocalError: local variable 'locs' referenced before assignment

I did read in other posts that the solution to this is to use global locs after I define the function. However, there are two def() functions in which locs = appears. I've tried inserting global locs under one of the def functions and running, and have also ran the code with global locs defined in both functions, but receive the same error in each case.

Traceback:

Traceback (most recent call last):
  File "model2.py", line 107, in <module>
    main()
  File "model2.py", line 94, in main
    if not locs:
UnboundLocalError: local variable 'locs' referenced before assignment

Relevant Code:

def extract_features(img_path):
  #  global locs #tried it here and got the same error
    X_img = face_recognition.load_image_file(img_path)
    locs = face_locations(X_img, number_of_times_to_upsample = N_UPSCLAE)
    if len(locs) == 0:
        return None, None
    face_encodings = face_recognition.face_encodings(X_img, known_face_locations=locs)
    return face_encodings, locs

def predict_one_image(img_path, clf, labels):
    #global locs #tried it here with same error
    face_encodings, locs = extract_features(img_path)
    if not face_encodings:
        return None, None
    pred = pd.DataFrame(clf.predict_proba(face_encodings),
                        columns = labels)
    pred = pred.loc[:, COLS]
    return pred, locs

 print("classifying images in {}".format(input_dir))
    for fname in tqdm(os.listdir(input_dir)):
        img_path = os.path.join(input_dir, fname)
        try:
            pred, locs = predict_one_image(img_path, clf, labels)
        except:
            print("Skipping {}".format(img_path))
        if not locs:
            continue
        locs = \
            pd.DataFrame(locs, columns = ['top', 'right', 'bottom', 'left'])
        df = pd.concat([pred, locs], axis=1)

if __name__ == "__main__":
    main()

Am I inserting global locs in the wrong place?


Solution

  • The problem is not with global/local variables nor with the functions at all.

    It is simply because of the try/except block:

            try:
                pred, locs = predict_one_image(img_path, clf, labels)
            except:
                print("Skipping {}".format(img_path))
            if not locs:
                continue
    

    Let's assume that predict_one_image does indeed raise an exception. This means neither pred nor locs will get to be defined. After that, the except block simply prints and the if not locs will fail.

    There are 2 easy ways you can fix this. Either initialize locs to None in case the call will fail:

            try:
                locs = None
                pred, locs = predict_one_image(img_path, clf, labels)
            except:
                print("Skipping {}".format(img_path))
            if not locs:
                continue
    

    Or, simply because you want to continue if locs is not defined (as I understand from the code), put the continue statement in the except:

            try:
                pred, locs = predict_one_image(img_path, clf, labels)
            except:
                print("Skipping {}".format(img_path))
                continue