1

Asking this question here, as the previous one was closed: https://stackoverflow.com/questions/41315555/traversing-a-linked-list-getting-the-output-twice

Update: I am using Python 3.6, Eclipse Neon.2 Release (4.6.2) (32 bit), and PyDev 5.5

I have created two classes, Node.py and UnorderedList.py.

Node.py is as follows:

class Node:
    #constructor
    def __init__(self,initdata):
        self.data = initdata
        self.next = None

    def hasNext(self):
        return self.next != None

UnorderedList.py :

class UnorderedList:   
    def __init__(self):
        self.head = None
        self.last = None

    def append(self,data):  
        temp = Node(data)
        if(self.head == None):
            self.head = temp
            self.last = self.head
        else:
            self.last.next = temp
            self.last = self.last.next

    def traverse(self):
        current= self.head
        while current != None:
            print(current.data)
            current = current.next

I am testing it, using the following code:

ul = UnorderedList()
ul.append(1)
ul.append(2)
ul.traverse() 

When I insert both classes in a single Python script, and run the code, the output, as expected, is:

1
2

However, when

  1. I put the two classes in different modules, in the following package structure,

Package structure

  1. put the import line on top of UnorderedList.py:

    import py_linked_lists.Node as Node
    
  2. make changes to append() as follows:

    def append(self,data):
        temp = Node.Node(data)
        #rest all code remains same
    
  3. Run the code, I get output twice:

    1
    2
    1
    2
    

Update: I tried out the suggestions in comments in https://stackoverflow.com/questions/41315555/traversing-a-linked-list-getting-the-output-twice, and was successful in preventing the output from coming twice, by using the if __name__ == "__main__"
guard block, as follows, in UnorderedList.py:

if __name__ == "__main__":

    ul = UnorderedList()
    ul.append(1)
    ul.append(2)
    ul.traverse()

Output:

1
2

Thanks to @Blckknght for that.

As i saw in the answers here, What does if __name__ == "__main__": do?, in case I do not use if __name__ == "__main__", the Node class which I import from py_linked_lists.Node will also get executed.

What I am not able to understand is how execution of Node.py impacts the output, when there is no such code there, just a class structure present.

Community
  • 1
  • 1
satvik.t
  • 423
  • 4
  • 19

1 Answers1

3

I got the answer, taking a cue from @nitind's comment. I had the following in __init__.py of py_linked_lists:

import py_linked_lists.UnorderedList as UnorderedList

As I learnt from https://stackoverflow.com/a/448311/4515198, the package's __init__.py is loaded every time we run a a module in the package,

In this case, the __init__.py of py_linked_lists will be loaded before the module UnorderedList.py is executed. So, the module UnorderedList.py was loaded as a import from __init__.py, before being executed as the main module. Hence, I got the output twice.

To confirm, I added the following in UnorderedList.py:

if __name__ == "__main__":
    print("Name is",__name__) 
    ul = UnorderedList()
    ul.append(1)
    ul.append(2)
    ul.traverse()
else:
    print("Name is",__name__)
    print("UnorderedList also being imported")
    print("---------------------------------")

the output:

Name is py_linked_lists.UnorderedList
UnorderedList also being imported
---------------------------------
Name is __main__
1
2

which clarifies that, UnorderedList.py was first loaded as in import from __init__.py, hence __name__ was equal to py_linked_lists.UnorderedList, and so, the else part was executed.

Then, the module UnorderedList.py was loaded as the main module, hence __name__ was equal to __main__ and the if part was executed, justifying the output above.

Community
  • 1
  • 1
satvik.t
  • 423
  • 4
  • 19