split python source code into multiple files?

Python

Python Problem Overview


I have a code that I wish to split apart into multiple files. In matlab one can simply call a .m file, and as long as it is not defined as anything in particular it will just run as if it were part of the called code. Example (edited):
test.m (matlab)

function [] = test()
    ... some code using variables ...
    test2

test2.m (matlab)

... some more code using same variables ...

Calling test runs the code in test as well as the code in test2.

Is there a similar way for python, to put ... some more code ..., into an external file, that will simply be read as if it is in the file that it is called from?

Python Solutions


Solution 1 - Python

Sure!

#file  -- test.py --
myvar = 42
def test_func():
    print("Hello!")

Now, this file ("test.py") is in python terminology a "module". We can import it (as long as it can be found in our PYTHONPATH) Note that the current directory is always in PYTHONPATH, so if use_test is being run from the same directory where test.py lives, you're all set:

#file -- use_test.py --
import test
test.test_func()  #prints "Hello!"
print (test.myvar)  #prints 42

from test import test_func #Only import the function directly into current namespace
test_func() #prints "Hello"
print (myvar)     #Exception (NameError)

from test import *
test_func() #prints "Hello"
print(myvar)      #prints 42

There's a lot more you can do than just that through the use of special __init__.py files which allow you to treat multiple files as a single module), but this answers your question and I suppose we'll leave the rest for another time.

Solution 2 - Python

I am researching module usage in python just now and thought I would answer the question Markus asks in the comments above ("How to import variables when they are embedded in modules?") from two perspectives:

  1. variable/function, and
  2. class property/method.

Here is how I would rewrite the main program f1.py to demonstrate variable reuse for Markus:

import f2
myStorage = f2.useMyVars(0) # initialze class and properties
for i in range(0,10):
    print "Hello, "
    f2.print_world()
    myStorage.setMyVar(i)
    f2.inc_gMyVar()
print "Display class property myVar:", myStorage.getMyVar()
print "Display global variable gMyVar:", f2.get_gMyVar()

Here is how I would rewrite the reusable module f2.py:

# Module: f2.py
# Example 1: functions to store and retrieve global variables
gMyVar = 0
def print_world():
    print "World!"
def get_gMyVar():
    return gMyVar # no need for global statement 
def inc_gMyVar():
    global gMyVar
    gMyVar += 1  

# Example 2: class methods to store and retrieve properties
class useMyVars(object):
    def __init__(self, myVar):
        self.myVar = myVar
    def getMyVar(self):
        return self.myVar
    def setMyVar(self, myVar):
        self.myVar = myVar
    def print_helloWorld(self):
        print "Hello, World!"

When f1.py is executed here is what the output would look like:

%run "f1.py"
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Display class property myVar: 9
Display global variable gMyVar: 10

I think the point to Markus would be:

  • To reuse a module's code more than once, put your module's code into functions or classes,
  • To reuse variables stored as properties in modules, initialize properties within a class and add "getter" and "setter" methods so variables do not have to be copied into the main program,
  • To reuse variables stored in modules, initialize the variables and use getter and setter functions. The setter functions would declare the variables as global.

Solution 3 - Python

Python has importing and namespacing, which are good. In Python you can import into the current namespace, like:

>>> from test import disp
>>> disp('World!')

Or with a namespace:

>>> import test
>>> test.disp('World!')

Solution 4 - Python

You can do the same in python by simply importing the second file, code at the top level will run when imported. I'd suggest this is messy at best, and not a good programming practice. You would be better off organizing your code into modules

Example:

F1.py:

print "Hello, "
import f2

F2.py:

print "World!"

When run:

python ./f1.py
Hello, 
World!

Edit to clarify: The part I was suggesting was "messy" is using the import statement only for the side effect of generating output, not the creation of separate source files.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarkusView Question on Stackoverflow
Solution 1 - PythonmgilsonView Answer on Stackoverflow
Solution 2 - Pythonuser3078690View Answer on Stackoverflow
Solution 3 - PythonAli AfsharView Answer on Stackoverflow
Solution 4 - PythonCarl GronerView Answer on Stackoverflow