0

My List class has a nested _Node class within it. With these 2 classes, I can:

  • Initialize an object of type List within List.
  • Initialize an object of type _Node within List.
  • Initialize an object of type List within _Node.

I can't, however, initialize a _Node within a _Node. The last line of the code is below causes NameError: global name '_Node' is not defined

class List:
    def __init__(self):
        self.root = None
        self.brother = None

    def set_root(self):
        self.root = self._Node()

    def set_brother(self):
        self.brother = List()

    def set_root_next(self):
        self.root.set_next()

    class _Node:
        def __init__(self, next_node=None, data=None):
            self.next_node = next_node
            self.data = data

        def set_next(self):
            self.next_node = _Node()

if __name__ == '__main__':
    x = List()
    x.set_root()
    x.set_brother()
    x.set_root_next()

How do I solve this? Making the _Node class unnested works but I am planning to have many types of list in the same file. All accompanying nodes will inherit from a single abstract class so keeping this structure is important.

Yves Gurcan
  • 1,096
  • 1
  • 10
  • 25
LismUK
  • 119
  • 1
  • 8
  • Where do you initialize the `_Node` class? It might simply be out of scope. – Piotr Kamoda Feb 27 '17 at 15:40
  • To be honest, I would rather use `None` as the default value for the next node. It makes a cheap and easy way to check if there is a successor. Also, do not use getters/setters, prefer [properties](http://stackoverflow.com/questions/6618002/python-property-versus-getters-and-setters). – farsil Feb 27 '17 at 15:45
  • @everyone I genuinely appreciate the code quality comments but this was just quickly typed code to illustrate my problem. My actual code looks nothing like this :) – LismUK Feb 27 '17 at 15:57

1 Answers1

2

Try using self.__class__() instead

class List:
    def __init__(self):
        self.root = None
        self.brother = None

    def set_root(self):
        self.root = self._Node()

    def set_brother(self):
        self.brother = List()

    def set_root_next(self):
        self.root.set_next()

    class _Node:
        def __init__(self, next_node=None, data=None):
            self.next_node = next_node
            self.data = data

        def set_next(self):
            self.next_node = self.__class__()

if __name__ == '__main__':
     x = List()
     x.set_root()
     x.set_brother()
     x.set_root_next()
farghal
  • 281
  • 1
  • 5
  • Thanks! Nice and simple, but d'you (or does anyone) know why my code is wrong? As I understand it the scope of the inner class should still allow itself to be instantiated, just like the outer class does. – LismUK Feb 27 '17 at 15:53