1

Context: I'm trying to migrate code from Matlab to python. Where in matlab, if you put two files under the same folder, the only thing you need to do to run commend lines or funciton from other script, is to simply type the file name. i.e. in file1.m if I type file2.m it will automatically run all lines of code from file2.m and with global variables shared in the same work space.

I tried to do the similiar things in python. However, even after read the posts online, I'm still a little confused.

Related posts:

From :

Run a python script from another python script, passing in args

What is the best way to call a script from another script?

Difference between subprocess.Popen and os.system

Calling a python script with input within a python script using subprocess

So I have the following options each seemed to have its unique strength, but the posts did not make a clear comparation between all of them.

import 
os.system
os.popen()
subprocess.Popen()
subprocess.call()
execfile

or simply

exec(open(dir+'\\a.py').read())
print(x) #outputs 1

The way I needed it to work is to use let file2.py us the same variables in file1.py, and that the variables generated by file2.py can be read by file1.py freely just like running a sequence of commend in one file, or that running it in same workspace in Matlab.

Some people mentioned that execfile can not pass argument??? thus the best way is to use os.system, some other people also mentioned that subprocess is better than os.system, but I'm not sure if using subprocess will affect the usage of varibles differently?? also somepeople used subprocess.Propen() and someone used subprocess.call(). But the way I looked, exec(open(dir+'\a.py').read()) seemed to be the closest way that I was thinking for this process.

Which one should I be using and why it's better?

Can you make a "catalog" or table bascially clearfing which one should I be using what type of circumstance?

2 Answers2

1

The Pythonic way would be to make file2.m into a module, and then import it in file1. Thus all functions from file2 are available in file1. If file2.m contains code that is directly executed (as opposed to just providing some functions), this code should be made into a function as well.

Do not stick with the global variable ansatz of Matlab. It's very bad form in Python. Once you get used to the Python Way, you'll find it awkward and out-of-place.

Putting the code from file2.m into a function has a really nice side effect: it forces you to think of a suitable name for the function. Using parameters instead of global variables will make data dependencies explicit rather than implicit, and as the Zen of Python says, explicit is better than implicit.

digitalarbeiter
  • 2,295
  • 14
  • 16
  • Thank you. I thought about that, but the issue is that each files of the program defined a lot of useful dependent variables, parameters, and matrix, so it's almost impossible to write them in functional representation and then resigns variables from local to global space. –  Nov 01 '18 at 18:41
  • I can imagine that this is quite a daunting task. I would like to encourage you to try and put in the effort. It _will_ pay off in the long run, and will make your analyses easier to understand, more robust, and more reliable, too. – digitalarbeiter Nov 01 '18 at 20:17
1
from file2 import *

will make all the definitions in file2 available in the current file's namespace.

There is a good reason everybody says don't do that; but that is probably the simplest and most pythonic solution to your immediate question.

The proper way to do it is to think hard about what your current code needs to know about file2 and make only those things available for import. A common encapsulation technique is to define a class, and only import that class.

from file2 import FileTwoClass

instance = FileTwoClass()
instance.frobnicate(parameterfile='./params')
for goose in instance.geese(color='green'):
    flaps = instance.flaps(goose)
    instance.hovercraft().eject(goose, flaps+1)

As you can see in this - purely fictional! - example, quite a lot of functionality can be indirectly exposed as object attributes and methods. Ideally, there should be no globals at all - maybe a class attribute or a single list of object instances will be the vehicle, but without any details about your code, it's impossible to make any concrete recommendations.

Steven Kryskalla
  • 14,179
  • 2
  • 40
  • 42
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thank you so much! So does it also automatic run the foeloops in the file as well? –  Nov 01 '18 at 18:49
  • I don't understand the question, but maybe I can guess. If `file2` contains bare code (anything not inside a `def` or similar) then that will run immediately when Python reads the file. A common guard against that is to put it inside a `if __name__ = '__main__':` condition. Then that code will execute if you run `python file2.py` on the command line, but not if you `import file2` from another Python script or module. – tripleee Nov 01 '18 at 18:58