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

Unlike Java, in python, when a module is imported into another module and the module method is called, why is the code in the body executed and not just the code in the method?

Example (taken from another SO question):

one.py file

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 only want the func()

method to execute one.py

, and why I decided to import and then call it, what should I do? Why is this done in the first place? I know that it gets called when you import it because of the operator import one

. Looking for what prompted the python designers to do it this way!

+3


source to share


4 answers


Programming languages ​​can have several different types of syntax elements. Most languages, for example, will display expressions and expressions that are different. Some languages, such as Java, have other syntax elements at the top level. For example, you cannot write some statements at the top level or in a class, but if you want to put a class definition at the top level or a method in a class, that’s just fine.

Perhaps you could think about Java having a top-level declarative part that switches to imperative (s) as you go deeper, and then probably an expression as you go even further. But Python doesn't really work that way. Python has a distinction between expressions and operators, but it doesn't actually contain a top-level declarative syntax element. You might be thinking about this:

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

      

... just like in Java as it can only appear in a specific context. But no: in Python, a function definition is an instruction, just like a class definition, like an assignment.

Because of this project, it is not possible to "just import the definitions": in order for the definitions to be created, the code to create the definitions has to be run.

I encourage you to think about the following case. In Python, if you want to create an enum (without the fancy new module enum

), you can do something like this:

FOO, BAR, BAZ = range(3)

      



To the human eye, this is perhaps the definition we want to use when we import the module. But how is this fundamentally different from something like that you might expect in __main__

?

name = input("What your name? ")

      

There really isn't any difference, so Python doesn't try to tell the difference; when the module is imported, the code is executed.


Bonus: similar behavior in Java

Think about it:

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...");
    }
}

      

+5


source


The key difference between Java and Python (in this case) is that Java has a separate compilation step - using javac

to create class files. Whereas, with Python, this compilation is done at runtime. Therefore, when importing a module, Python has to compile all the source code of the module into byte code. This includes all of these print statements as well as the creation of your functions and classes. What you are asking would be like asking to javac

only compile part of the .java file.



+2


source


It runs because all the code in the module is executed, including the function definition, on first import. If you don't want the code to execute, put it in the main stanza.

+1


source


When you import a module in Python, the entire file is executed. This creates all the functions and variables that are part of the module. It makes no distinction between just executing function or class statements.

I believe the general pattern for having executable code in a library is:

# one.py
def func():
    print "In file!"

def main():
    # do stuff here
    pass

if __name__=="__main__":
    main()

      

Then you can execute the file directly python one.py

or you can import one

and use one.func()

from it.

0


source