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

Time:02-23

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()

CodePudding user response:

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.

CodePudding user response:

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()
  • Related