2

Can someone please tell me what's wrong with the following Python code.

def education():

    class College:
   
        type = "University"

        def __init__(self, name, location):
            self.name = name
            self.location = location

        iet = College("IET", "Kanpur")
        jim = College("JIM", "Lucknow")

        edu1 = print("IET is a {}".format(iet.__class__.type))
        edu2 = print("JIM is also a {}".format(jim.__class__.type))

        loc1 = print("{} is located in {}".format(iet.name, iet.location))
        loc2 = print("{} is located in {}".format(jim.name, jim.location))
        
    return edu1, edu2, loc1, loc2

education()

NameError: free variable 'College' referenced before assignment in enclosing scope

I get the above NameError while calling the function.

Thanks in advance.

2 Answers 2

2

You are trying to create College() objects inside the class College, but outside any function in that class. That is what's causing the error.

If you unindent the part after __init__, it will work, like so:

def education():
    class College:
        type = "University"

        def __init__(self, name, location):
            self.name = name
            self.location = location

    iet = College("IET", "Kanpur")
    jim = College("JIM", "Lucknow")

    edu1 = print("IET is a {}".format(iet.__class__.type))
    edu2 = print("JIM is also a {}".format(jim.__class__.type))

    loc1 = print("{} is located in {}".format(iet.name, iet.location))
    loc2 = print("{} is located in {}".format(jim.name, jim.location))

    return edu1, edu2, loc1, loc2


education()

However, I would advise to define the class College before the function, like so:

class College:
    type = "University"

    def __init__(self, name, location):
        self.name = name
        self.location = location
        
        
def education():
    iet = College("IET", "Kanpur")
    jim = College("JIM", "Lucknow")

    edu1 = print("IET is a {}".format(iet.__class__.type))
    edu2 = print("JIM is also a {}".format(jim.__class__.type))

    loc1 = print("{} is located in {}".format(iet.name, iet.location))
    loc2 = print("{} is located in {}".format(jim.name, jim.location))

    return edu1, edu2, loc1, loc2


education()

Edit: You're declaring type in class College, thereby hiding Python's type. It is not advised to use names for variables that are default keywords in Python, such as list, dict, type.

Edit2: As Ishwar pointed out, you're storing the return from print statements in loc1 and loc2. print() always returns None, so there is no use in storing it in variables. If you wanted to store the formatted strings, store those in variables and then print those variables.

Sign up to request clarification or add additional context in comments.

1 Comment

Also the print object is stored in returned variables instead of the actual value. This is useless as print returns None. Instead string must be stored in edu1, edu2, loc1 and loc2.
0

Python uses indentation to determine if code is part of the function or part of the class. Here your code referencing College is indented such that it forms part of the class and not your function.

Additionally, you are defining you class inside your function. I can see no good reason why you should do this. Also your variable type is a reserved keyword, so its advised to change this to something else, such as college_type. Lastly the print statement returns None, so none of your variables will be populated with any data.

See the code below:

class College:
   
        college_type = "University"

        def __init__(self, name, location):
            self.name = name
            self.location = location

def education():
    iet = College("IET", "Kanpur")
    jim = College("JIM", "Lucknow")
    
    edu1 = iet.__class__.college_type
    edu2 = jim.__class__.college_type
    print("IET is a {}".format(edu1))
    print("JIM is also a {}".format(edu2))

    loc1 = iet.location
    loc2 = jim.location
    print("{} is located in {}".format(iet.name, loc1))
    print("{} is located in {}".format(jim.name, loc2))
        
    return edu1, edu2, loc1, loc2

education()

4 Comments

don´t use type = bla, `type´ is a reserver word in python
Good catch @FrancoMorero
Also the print object is stored in returned variables instead of the actual value. This is useless as print returns None.
Very true @R. dV

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.