Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In python,why does the code in class body gets executed only when a method of another module is called?

Tags:

python

Unlike Java, in python when a module is imported into another module and a module's method is called, why does the code in the body gets executed instead of only the code in the method?

Example (taken from another SO question):

file one.py

def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")

file two.py

import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

and when I run this :

python two.py

I get :

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

If I want only the func() method of one.py to be executed and that's why I chose to import and then call it, what should I be doing? Why does it get executed in the first place? I know it gets called when its imported because of the statement import one. Looking for what prompted python designers to do it this way!

like image 860
theblackpearl Avatar asked Oct 20 '25 03:10

theblackpearl


1 Answers

Programming languages can have several different kinds of syntactic elements. Most languages, for example, will have statements and expressions, which are distinct. Some languages, like Java, have other syntactic elements at the top level. You cannot, for example, write some statements at the top level or in a class, but if you wanted to put a class definition at the top level or method in a class, that would be just fine.

You could, perhaps, think of Java as having a declarative part at the top level that switches to imperative (statements) once you go deeper, and then likely an expression as you go even further. But Python doesn’t really work that way. Python does have a distinction between expressions and statements, but it doesn’t really have a top-level declarative syntactic element. Perhaps you’re thinking of this:

def greet(name):
    print("Hello, {}!".format(name))

…in the same way as you would in Java, in that it can only appear in a certain context. But no: in Python, a function definition is a statement, as is a class definition, as is an assignment.

Because of this design, it’s infeasible to “just import the definitions”: in order for the definitions to be created, the code to create the definitions must be run.

I urge you to think of the following case. In Python, if you want to create an enumeration (without the fancy new enum module), you might do something like this:

FOO, BAR, BAZ = range(3)

To the human eye, that’s probably a definition we want to exist when we import the module. But how is that fundamentally different from something like this, which you might expect to exist in __main__?

name = input("What's your name? ")

There really is no difference, so Python makes no attempt to try to distinguish them; when you import a module, the code is executed.


Bonus: Similar behavior in Java

Think about this:

public class Test {
    static {
        System.out.println("Wait, what? Code is running without being called?");
    }

    public static void main(String[] args) {
        System.out.println("Nothing to see here, move along now...");
    }
}
like image 138
icktoofay Avatar answered Oct 26 '25 21:10

icktoofay