1

I am newbie to python, Q1 : I am wondering, Why print statement is executing multiple times, even though I called school1.print_name() only once?

Q2 : What is purpose of __init__.py that is being created when creating a new package?

Q3 : What difference does it make creating an object from otherfile.py and __init__.py?

(Note: I debugged the code from otherfile.py and init.py, where the script is not terminating after calling the school1.print_name(), but it is running again from the start of script)

SameFile.py

class School:

    def __init__(self, name):
        self.name = name

    def print_name(self):
        print("School name is : " + self.name)

school1 = School("DPS") # 1 
school1.print_name()`   # 2
# These 1 and 2 lines are removed from this file when running from otherfile.py and __init__.py

o/p :

School name is : DPS

OtherFile.py

import School

school1 = School("DPS")
school1.print_name()

o/p :

School name is : DPS
School name is : DPS #why did it print second time

__init__.py

import School

school1 = School("DPS")
school1.print_name()

o/p :

School name is : DPS
School name is : DPS #why did it print second time
rinkert
  • 6,593
  • 2
  • 12
  • 31
Rahul Reddy
  • 110
  • 11
  • 1
    You should add `if __name__ == "__main__"` to the file that defines the class `School`, see [this](https://stackoverflow.com/questions/419163/what-does-if-name-main-do) post. Give your school different names across files to see what is actually happening! – rinkert Oct 25 '19 at 15:27
  • 1
    Thanks @rinkert !! Figured it out, What exactly happening. Appreciated :) – Rahul Reddy Oct 25 '19 at 15:37
  • In `__init__.py` Suppose... `school1 = School("DPS -- __init__")` `school1.print_name()` -------------------------------- O/P: `School name is : DPS -- __init__` `School name is : DPS -- __init__` Its printing multiple times now? Whats happening now ? – Rahul Reddy Oct 25 '19 at 15:47
  • You can best leave your `__init__.py` empty, add the name == main to the file that defines `School`, and do an `import School` at the top of the files that require `School`. – rinkert Oct 25 '19 at 16:16

2 Answers2

0

When you import a module, functions in that module are executed. To prevent this problem you can use `if name == "main":

class School:

    def __init__(self, name):
        self.name = name

    def print_name(self):
        print("School name is : " + self.name)
if __name__ == "__main__":
    school1 = School("DPS") # 1 
    school1.print_name()`   # 2

For Q2 and Q3 refer this question: What is __init__.py for?

  • Functions in a module aren't executed on import with or without `if __name__ == "__main__"` unless those functions are executed in the modules `__init__.py` – Matthew Barlowe Oct 25 '19 at 16:47
  • @MatthewBarlowe, can I know where exactly you are linking the above point ? thanks – Rahul Reddy Oct 25 '19 at 17:53
  • @RahulReddy the comment says "When you import a module, functions in that module are executed' this is incorrect unless those functions are specified to run in the modules `__init__`.py file. `if __name__ == "__main__":` has nothing to do with what happens when the file is imported but rather when the file is run at the command line as a standalone script – Matthew Barlowe Oct 25 '19 at 19:07
0

Consider the following file structure:

mymodule/
    __init__.py
    Buildings.py

Let's keep __init__.py empty for the moment. Buildings.py looks as follows:

class School:

    def __init__(self, name):
        self.name = name

    def print_name(self):
        print("School name is : " + self.name)


if __name__ == '__main__':
    school1 = School("DPS -- Buildings.py")
    school1.print_name()

Use your module in a file test.py as follows:

from mymodule.Buildings import School

school = School('DPS - test.py')
school.print_name()

This will correctly print DPS - test.py, as we would expect. Since __init__.py is empty, nothing else will be printed. If we however put any print statement in the __init__.py, this will be displayed when importing anything from the mymodule module.

Change __init__.py:

from mymodule.Buildings import School 

print('__init__.py is loaded!')

school = School('DPS - __init__.py')
school.print_name()

and run test.py, which will result in the following output:

__init__.py is loaded!
School name is : DPS - __init__.py
School name is : DPS - test.py

So you can see, that first __init__.py is executed upon loading of the module, and then the other lines in test.py are executed.

rinkert
  • 6,593
  • 2
  • 12
  • 31
  • Yes this is fine @rinkert!! suppose If I am running code from `__init__.py`, then output goes like this: --------------------- `__init__.py is loaded!` ...... `School name is : DPS - __init__.py` ..... `__init__.py is loaded!` ..... `School name is : DPS - __init__.py` The output is printed multiple times – Rahul Reddy Oct 25 '19 at 17:44