user14383280
user14383280

Reputation:

Why I can't refer to class variable from nested class?

In simple case I can call teacher in loh function:

class Student:
   teacher = 'Mrs. Jones'

   def __init__(self, name):
       self.name = name
    
def loh():
  print(Student.teacher)

loh()

### Mrs. Jones

But, If I try to do that next way, I got mistake "not defined". Why?

class Student:
  class UnderStudent:
    teacher = 'Mrs. Jones'
  def f():
    print(UnderStudent.teacher)
  f()

Upvotes: 1

Views: 60

Answers (2)

ShadowRanger
ShadowRanger

Reputation: 155418

You can't do it that way for the same reason you can't just say teacher without qualifying it with self or Student (Student.teacher is a class attribute of Student in your first example; in your second example, Student.UnderStudent is a class attribute of Student that just happens to be a class itself). UnderStudent doesn't exist at global scope, it only exists within the scope of Student, just like teacher did.

You also have to invoke f after Student is fully defined, because until you exit the scope of Student's definition, Student doesn't exist in global scope (so you can't use it to find UnderStudent). To fix, you could do:

class Student:
  class UnderStudent:
    teacher = 'Mrs. Jones'
  def f(self):
    print(Student.UnderStudent.teacher)
    # or
    print(self.UnderStudent.teacher)

Student().f()

Upvotes: 4

chepner
chepner

Reputation: 531185

f tries to lookup UnderStudent in the global scope, but the name isn't defined there; it's only defined in the namespace of the class statement, which turns the name into a class attribute.

class Student:
    class UnderStudent:
        teacher = 'Mrs.Jones'
    def f(self):
        print(self.UnderStudent.teacher)
        # or print(Student.UnderStudent.teacher)

Nested classes are rare in Python, as there is no restriction on having multiple top-level classes in the same file as in some other languages.

Upvotes: 4

Related Questions