-4

I was implementing Graph in python, I had written a following code:

class k: 
    class Graph:
          def __init__(self,v): 
                 array=[Adlist() for i in range(v)] 
    class Adlist:
          def __init__(self):
                 head=[]
    def printgraph():
          for i in array:
                 print(i.head)
if __name__==__main__
     l=k()
     l.Graph(5) 
     l.printgraph()

After running the code section, I got an error 'Adlist is not defined.'

kushal kochar
  • 25
  • 1
  • 4
  • 2
    What is the error you are getting? What have you done to try to remedy the problem? – ktb Aug 03 '18 at 03:28
  • Yes I was not able to create object of Graph. It shows Adlist in not defined.. – kushal kochar Aug 03 '18 at 03:36
  • 2
    Please give us a [mcve]. As written, this raises a `NameError` on `__main__`, which I doubt is the problem you're asking about. And include the exception traceback in the question, don't just give us a vague description in a comment. – abarnert Aug 03 '18 at 03:37
  • Does Graph do anything else besides hold `array`, and does `Adlist` do anything else besides hold `head`? – Zizouz212 Aug 03 '18 at 03:40
  • More than likely the problem is that `Adlist()` being a member of the class `k` must be referenced using a qualified name: either `self.Adlist()` or `k.Adlist()`. If it's something else, please improve the question. – ktb Aug 03 '18 at 03:41
  • @ktb That's not the only issue: if `printgraph` is to be an instance method, it needs `self` as a parameter, and then reference array as `self.array` (assuming that `array` would then become an attribute). – Zizouz212 Aug 03 '18 at 03:43
  • Possible duplicate of [Python - reference inner class from other inner class](https://stackoverflow.com/questions/42185472/python-reference-inner-class-from-other-inner-class) – user202729 Aug 03 '18 at 03:44

1 Answers1

0

The short version is: You want k.Adlist here, not Adlist. It's similar to the fact that when you want to access an attribute, you need self.spam, not just spam, although the details are different.


The medium-long version is:

While a class body does create a namespace, it's not like a function's body.

In particular, the locals in a class body cannot be captured by classes or functions defined within the class body, the way function locals can be captured by classes r functions defined within the function body.

However, when the class statement is executed, the namespace of that class body becomes the set of attributes of the class object. So, you can access those variables through the class (or through any of its instances, but that isn't relevant here).


Meanwhile, there are multiple other problems with your code:

  • __main__ isn't defined anywhere. You probably meant '__main__'?
  • The array that you create in Graph.__init__ is just a local variable, which goes away as soon as __init__ returns, so nobody can ever access it again. You probably wanted self.array here.
  • The head in Adlist.__init__ has the same problem.
  • The printgraph function doesn't take a self parameter, so it can't be called as a method on a k instance.
  • The printgraph function tries to access something named array, but there's nowhere it could get such a thing from. Sure, instances of the class Graph (if you fix the first problem) have an array attribute, but there's no connection between a k instance and any Graph instance. As far as that k object knows, there could be 300 Graphs, or none at all. Maybe you wanted this to be a method of Graph, not of k?
  • l.Graph(5) creates a Graph instance and then immediately discards it. That isn't very useful.
  • Calling l.Graph instead of k.Graph, while legal, is potentially a bit misleading—it implies to the reader that there's some kind of connection between the specific instance l and the Graph, but there really isn't.

Putting it all together:

class k: 
    class Graph:
        def __init__(self, v):
            self.array = [k.Adlist() for i in range(v)] 
        def printgraph(self):
            for i in self.array:
                print(i.head)
    class Adlist:
        def __init__(self):
            self.head = []

if __name__ == '__main__':
     g = k.Graph(5) 
     g.printgraph()

Of course this will just print five empty lists, but that's better than a NameError and another NameError when you fix that and so on…

abarnert
  • 354,177
  • 51
  • 601
  • 671