0

I am trying to organize my functions into classes. I want to use the attribute self.file_list from class 'Outer' in class 'Inner'.

class Outer:
    """Outer Class"""
    def __init__(self, file_list):
        self.file_list=file_list
        ## instantiating the 'Inner' class
        self.inner = self.Inner()


    ## inner class
    class Inner:
        """First Inner Class"""
        def __init__(self):
            print (Outer.file_list)  <-- this line doesn't work 

            pass
clean =Outer (['cats', 'dogs'])

However I am getting this error:

<ipython-input-63-0dfab321da74> in __init__(self)
     10         """First Inner Class"""
     11         def __init__(self):
---> 12             print (self.file_list)
     13 
     14             pass

AttributeError: 'Inner' object has no attribute 'file_list'

How do I access the attribute self.file_list in the inner init method? Or what is the conventional way of grouping functions together in a class?

Leo
  • 1,176
  • 1
  • 13
  • 33
  • 2
    There is no implicit relationship between an inner class and an instance of an outer class, so you have to set up that relationship yourself (e.g. pass a `parent` parameter when constructing `Inner`, make a factory function inside `Outer` that sets a member of `Inner`, etc.) OR don't rely on that relationship at all and just pass down the data that you care about. – 0x5453 Sep 30 '19 at 13:18
  • The conventional way would be _not_ to do that at all. – L3viathan Sep 30 '19 at 13:19
  • 1
    Why not? Aren't there any valid reasons to create an inner class? Django, for example uses an inner Meta class throughout a lot of its classes. – Nico Griffioen Sep 30 '19 at 13:22

1 Answers1

4

Outer is the class, and file_list is an instance property of that class. You can not access Outer.file_list, because it does not exist.

When creating an instance of Inner, you'll needy to pass the Outer parent instance to be able to access its members.

Changing your code to:

class Outer:
    """Outer Class"""
    def __init__(self, file_list):
        self.file_list=file_list
        ## instantiating the 'Inner' class
        self.inner = self.Inner(self)


    ## inner class
    class Inner:
        """First Inner Class"""
        def __init__(self, outer_parent):
            print (outer_parent.file_list)

            pass

Should make it work.

Nico Griffioen
  • 5,143
  • 2
  • 27
  • 36
  • Would this be conventionally used or not ? I dont want to start doing thing that aren't the norm – Leo Sep 30 '19 at 13:25
  • 1
    Whatever you can achieve with inner classes, you can also achieve without them. However, inner classes, and this type of pattern can be used to structure your code, and this is a perfectly valid way of implementing some encapsulated functionality. See this question for more detail on the how and why of inner classes: https://stackoverflow.com/questions/719705/what-is-the-purpose-of-pythons-inner-classes – Nico Griffioen Sep 30 '19 at 13:30