The MathWorks introduced the py module for MATLAB in 2014. This module provides a direct binary interface between MATLAB and Python, opening vast new possibilities for both languages. In addition to making it possible to call any Python function, MATLAB’s py module allows one to create native Python objects within MATLAB. Such variables retain their full complement of Python methods—for example, a native Python string created in MATLAB can call all its 40 methods, from .capitalize() to .zfill().
The py module has improved with each new release of MATLAB. MATLAB code examples in this book use MATLAB 2020b, so if you’re working with an older version of MATLAB, some of the examples may not work.
This chapter just introduces the basic mechanics of using the py within MATLAB. Appendix A contains a list of “recipes” that show complete MATLAB programs that call Python to solve problems the core MATLAB product can’t solve on its own.
6.1 Configure MATLAB to Recognize Python
The first step to using py in MATLAB is setting up a Python virtual environment with shared libraries that are compatible with MATLAB. The matpy environment described in Section 2.5.1 has been verified to work on Linux Ubuntu 20.04, Windows 10, and macOS 11.6, all with MATLAB 2020b.
Next, activate this environment, and invoke the matlab command from it:
Within MATLAB, check if it already recognizes Python, and if it doesn’t, update the configuration to point to your Python installation. The pyenv command will tell if MATLAB is already configured for interaction with Python.
Note in particular the last entry, “ExecutionMode: InProcess.” A troubleshooting option we’ll see in the next section is to change this to “OutOfProcess.”
If the pyenv command comes up empty, invoke it a second time telling it the path to your Python executable, for example:
On Windows, find the path to the Python interpreter by opening an Anaconda Prompt and entering where python.exe:
Specify the path to the Anaconda version rather than Microsoft’s! Microsoft’s version doesn’t come with NumPy, SciPy, or many of the additional modules you installed into your matpy virtual environment, so if you use it, most of the examples will fail.
MATLAB on Windows may complain with
Error using pyversion
Path argument does not specify a valid executable.
when setting the Python executable path with pyenv or pyversion. One solution to this error is to reinstall Anaconda, this time selecting “Install for all users.”
On Linux and macOS, the comparable command is which python3, done from a terminal which is configured for Anaconda Python.
Your MATLAB version will support a subset of available Python versions; 2020b supports Python 2.7, 3.6, 3.7, and 3.8. Both MATLAB and Python must be on compatible architectures, that is, both 64 bits or both 32 bits.
6.2 Does It Work?
There are many ways a MATLAB/Python hybrid environment can fail, most of which trace back to conflicting shared libraries (or DLLs in the Windows world). Both MATLAB and Anaconda’s Python distribution use the Intel Math Kernel Library (MKL), Intel’s OpenMP library, and Qt 5 libraries, among others—but the library versions aren’t necessarily at the same level. It is entirely possible for MATLAB or Python to crash because one called an incompatible library function from the other’s installation. The MathWorks’ ability to get these two large, complex applications to coexist peacefully most of the time is a considerable feat of software engineering.
Before proceeding, verify that MATLAB can load Python modules without difficulty. Let’s jump straight to a challenging command:
The successful case shows a long list of NumPy module attributes. If you see this, continue to the next section.
Python Error: ImportError.
Unable to resolve the name numpy.
Segmentation violation detected.
The last three errors can be caused by a Python installation that is not version consistent with, or not visible to, MATLAB; the Python installation does not have NumPy installed; or you are not in the matpy conda environment and are hitting shared library conflicts between MATLAB and Python.
Possible workarounds:
1) Change “ExecutionMode” reported by pyenv from the default “InProcess” to “OutOfProcess” with
2) [Linux only] Set the Python dynamic library load flag to 10:
I set this in my startup.m file on my Linux computer.
3) [Linux or macOS] If the terminal from which you configured matpy and then launched MATLAB shows an error about OpenMP library conflicts, try setting the environment variable KMP_DUPLICATE_LIB_OK to TRUE. This can be done in Python’s view of the environment variables within MATLAB with
I include the preceding two lines in my startup.m file on my macOS computer.
See Section 6.4 for details on creating and modifying startup.m.
If the module import still fails, it is likely lower-level libraries installed to your matpy environment won’t work with your version of MATLAB. There’s no clear method to determining the right versions though.
6.3 Importing (and Reloading) Python Modules
As mentioned in Section 3.14, any Python source file may be imported as a Python module. Functions and classes in a module file can only be accessed if the file is in the Python search path, sys.path (see Section 6.6 on how to add directories to the Python search path within MATLAB), or exists in the current directory. Once on the search path, functions and classes in the Python module can be accessed in MATLAB in two ways: directly through py or as an alias created with py.importlib.import_module().
As an example, say we have a Python file (a.k.a. a module), integrate.py, containing three functions that perform numeric integration: rectangle(), trapezoid(), and simpsons(). We can call the trapezoid() function using either of these methods:
Directly through py
Through a module import
The reload method only works for modules brought in with py.importlib.import_module(). Functions accessed through py.modulename.functionname() cannot be reloaded; the only option there is to restart MATLAB.
6.4 Configure startup.m for Python Work
MATLAB will run the commands in startup.m at the start of each session if it finds such a file in the userpath directory. On my Linux computer, this is
The location can be changed by calling userpath with the desired location, for example, userpath('/home/al/mfiles').
userpath is also the first directory in path, the collection of directories MATLAB searches to find m-files and compiled extensions. This directory is a perfect location for m-files containing utilities you use often.
Linux: Add to your startup.m file the line py.sys.setdlopenflags(int32(10));
Windows: Figure out the location of the Python executable associated with the matpy virtual environment and then add to your startup.m file a line that calls pyversion() with this path. This can be done in two steps. First, open an Anaconda Prompt, then
Add to your userpath directory a copy of, or a symbolic link to, py2mat.m, mentioned in Section 6.5.7 and listed in Appendix D. You will call this function frequently from MATLAB code that calls Python functions.
Tip A platform-independent way to edit your startup.m file is with this MATLAB command:
>> edit(fullfile(userpath,'startup.m'))
(If the file does not exist, you’ll be prompted on whether or not to create it; click Yes.)
My Linux-based startup.m looks like this:
On macOS, my startup.m is
6.5 Create Python Variables and Call Python Functions in MATLAB
We saw in Chapter 4 that Python and MATLAB data containers—lists, cell arrays, structs, dictionaries, numeric arrays—are similar but do not have a direct one-to-one mapping. Here, we’ll give explicit examples that show how to create native Python data containers within MATLAB, how to pass MATLAB data to Python functions, and how to convert native Python variables back to native MATLAB variables.
For now, all Python files mentioned in the following should be in the MATLAB working directory. Later in Section 6.6, we’ll show how to update the Python search path within MATLAB to allow MATLAB to find your Python code in other locations.
6.5.1 Scalars
Native Python doubles, integers, and strings can be created in MATLAB with the functions py.float(), py.int(), and py.str(). Despite their names, py.float() and py.int() create a 64-bit Python floating point value and a 64-bit Python integer.
py.complex() is not implemented in MATLAB 2020b, but Section 6.5.4 shows py.numpy.complex() can be used. In either case, this is superfluous as complex numbers—and doubles—transfer natively between MATLAB and Python.
Explicit conversion to Python scalars is unnecessary when calling Python functions in MATLAB; these conversions happen automatically. In the following, we create a 32-bit integer, a double, a complex number, and a string in MATLAB and pass them directly to a Python function. The Python function returns modified values back to MATLAB. Within Python, return n, x, c, s means “return a tuple with four values.” On the receiving end, MATLAB sees this tuple as a cell array—variable RV, for “return value”—having four items.
MATLAB 2020b: | Python: |
---|---|
>> n = int32(10); >> x = 3.1415; >> c = 5.5 - 6.6i; >> s = "in matlab"; >> RV = py.xfer.modify_scalars(n,x,c,s); >> pn = RV{1}.int64; >> px = RV{2}; % double: 1-to-1 >> pc = RV{3}; % complex: 1-to-1 >> ps = string(RV{4}); >> pn,px,pc,ps pn = int64 15 px = 15.7075 pc = 27.5000 -33.0000i ps = "IN MATLAB" | # file: xfer.py def modify_scalars(n,x,c,s): n += 5 x *= 5 c *= 5 s = s.upper() return n,x,c,s |
6.5.2 Lists and Cell Arrays
In Section 4.3, we showed that Python lists are analogous to MATLAB cell arrays. A native Python list is created by passing a cell array to py.list(). The list can be modified with any of the Python list methods:
MATLAB 2020b: | Python: |
---|---|
>> ca = {'a', int32(20), -9.8} >> ca = 1x3 cell array {'a'} {[20]} {[-9.8000]} >> RV = py.xfer.modify_list(ca); >> CA = RV.cell CA = 1x4 cell array {1x7 py.str} {[-9.8000]} {1x1 py.int} {1x1 py.str} | # from file xfer.py def modify_list(ca): # ca comes in as a tuple L = list(ca) L.append('flipped') L.reverse() return L |
Aside from –9.8, all elements of the CA cell array are native Python objects—not useful at all for MATLAB work; further conversion is needed. We present a generic Python-to-MATLAB data converter function, py2mat(), in Section 6.5.7. There, we’ll revisit this example and show how all elements of CA can be made MATLAB native.
6.5.3 Tuples
Python tuples (Section 4.4) can be created in MATLAB by passing a MATLAB array to the py.tuple() function. These are only needed when calling Python functions that explicitly expect a tuple argument—and in many cases, that requirement may be satisfied by a MATLAB array. As an example, recall NumPy’s function np.ones() takes a tuple describing the matrix dimensions as its first argument:
To make the same matrix in MATLAB, we can explicitly pass in a tuple like so:
(Recall also that NumPy only accepts integer arguments for matrix dimensions. Since MATLAB’s default numeric constant is a double, we have to first explicitly cast 3 and 5 to be 64-bit integers.)
The interface to np.ones() is rather forgiving though, and an array instead of an explicit tuple also works:
6.5.4 Numeric Arrays
Unlike scalars and cell arrays, MATLAB numeric arrays cannot be passed to Python functions directly. They must first be converted to NumPy arrays (Section 11.1) within MATLAB with py.numpy.array().
Similarly, NumPy arrays (“ndarrays”) returned by Python also require conversion to native MATLAB variables before they can be used for computation. While the py2mat() mentioned in the previous section can perform this conversion, here we cover the details of how such conversions are done.
MATLAB 2020b: | Python: |
---|---|
>> A = single([2.2 3.3; 4.4 -1]) A = 2x2 single matrix 2.2000 3.3000 4.4000 -1.0000 >> py_A = py.numpy.array(A) py_A = Python ndarray: 2.2000 3.3000 4.4000 -1.0000 >> RV = py.xfer.modify_arr(py_A) RV = Python ndarray: 2.4200 3.6300 4.8400 -1.1000 >> result = single(RV) result = 2x2 single matrix 2.4200 3.6300 4.8400 -1.1000 | # from file xfer.py def modify_arr(A): return A * 1.1 |
MATLAB has ten type functions which accept NumPy arrays: single, double, int8, int16, int32, int64, uint8, uint16, uint32, uint64. Absent are single- and double-precision complex conversion functions; as of MATLAB 2020b, the py.numpy.array() function does not accept complex arrays. Complex arrays must be split into their real and imaginary parts to cross the language divide.
Python-native scalar constants with explicit numeric types can also be created in MATLAB using NumPy functions described in Section 11.1.3, for example:
6.5.5 Dictionaries and Structs
MATLAB’s native key/value data type, container.Map , seems like the ideal counterpart to Python dictionaries, but maps are not supported:
Instead, Python a dictionary is associated with a MATLAB struct. A MATLAB struct passed to a Python function is seen by Python as a dictionary. Changes done to the dict in Python are seen by MATLAB as changes to the struct.
MATLAB 2020b: | Python: |
---|---|
>> x.a = 1; >> x.b = -1; >> x.c = 0.5; >> x x = struct with fields : a: 1 b: -1 c: 0.5000 >> pyx = py.xfer.modify_dict(x) pyx = Python dict with no properties. {'a': 1.0, 'b': -1.0, 'c': 0.5, 'new': 6.1} >> xnew = struct(pyx) xnew = struct with fields: a: 1 b: -1 c: 0.5000 new: 6.1000 | # from file xfer.py def modify_dict(d): d['new'] = 6.1 return d |
Methods to create, inspect, and update Python dictionaries within MATLAB are demonstrated as follows:
Create an empty dictionary:
Create a dictionary with initial values:
A limitation is that the odd numbered arguments to pyargs(), meaning the dictionary keys, may only be strings. Python dictionaries can, of course, have integer keys, among many other types, but adding such keys to a Python dictionary within MATLAB violates the rule that keys be valid MATLAB variables. The integer 7 may be a dictionary key in Python, but is clearly not an allowable variable name in MATLAB.
Show all keys:
Iterate over keys:
Retrieve a value with a key:
Add or change a key/value pair:
Remove a key/value pair:
6.5.6 Keyword Arguments
The following example calls the NumPy np.linspace() function with keyword arguments specifying the number of values and data type to return. Both Python and MATLAB versions are shown:
6.5.7 Python-to-MATLAB and MATLAB-to-Python Variable Converters
Appendix D has listings for py2mat() and mat2py(), MATLAB functions which convert, where possible, a Python variable within MATLAB into a native MATLAB variable and vice versa. Such conversions may be necessary to pass MATLAB data to Python functions and then convert data returned from Python functions back to native MATLAB variables. These functions can also be found in this book’s Github repository, https://github.com/Apress/python-for-matlab-development .
6.5.8 Traversing Generators
MATLAB cannot traverse generators using a simple for loop. Instead, they have to explicitly call Python’s next() function in a while loop. This Python generator, for example
can be traversed in MATLAB with
Python’s next() raises a StopIteration exception if it is called after the last item has been returned. The MATLAB code checks for this exception to leave the while loop cleanly. If any other error is caught, its message is printed.
A side note: Python’s range() function is not a generator. Instead, it is a “lazily evaluated” function and, as such, can be traversed with a for loop in MATLAB. The catch is that range() has list-like behavior which translates to cell-like behavior in MATLAB. This means the iteration variable i’s value must be dereferenced as i{1}:
6.5.9 Traversing zip()
A zipped Python list can be traversed in MATLAB with a conventional for loop if the call to py.zip() is explicitly expanded with py.list(). Using x as the iteration variable, the iteration item pairs are indexed as x{1}{1} and x{1}{2}:
6.6 Modifying the Python Search Path Within MATLAB
We saw in Section 3.14.3 that the Python list sys.path contains the module search path, the collection of directories Python scans to find code. The Python search path can be augmented in Python code with sys.path.append() just as MATLAB’s path can be expanded with addpath. Extending Python’s search path within MATLAB is less obvious. Although Python lists in MATLAB can use the .append() method, lists accessed as module parameters such as sys.path cannot. In other words, the sys module has among its many member functions and parameters the list sys.path , but one cannot use sys.path.append() from MATLAB.
6.6.1 Extending sys.path with an Alias
An interesting twist on .append()’s inability to update lists accessed as module parameters is that .append() works fine on aliases to such lists. Recall from Section 4.8 that a list assignment in Python such as newlist = oldlist merely creates an alias to oldlist; both newlist and oldlist point to the same data, and a change to either of them is reflected in both.
We can take advantage of this behavior to expand sys.path by using .append() on an alias to sys.path:
6.6.2 Extending sys.path with insert()
MATLAB’s insert() function can also modify Python lists. (Aside: insert() is a curious function. It has no built-in help, at least in MATLAB 2020b, and online documentation shows it as a function for adding data to SQLite, MongoDB, and other databases. More revealing is that its signature matches the Python .insert() method for lists—including requiring an explicit integer as the index argument. The obvious conclusion is that insert() is a direct interface to Python’s list .insert() method.)
The following examples show how to add a directory to the beginning of Python’s sys.path list and append a directory to the end of it:
6.6.3 Extending sys.path with append()
There’s an alternate way to achieve the same result by using Python’s append() function from the Python list module. Unfortunately, MATLAB does not offer the ability to cherry-pick individual functions from a module like Python’s from list import append, so we import everything from list. Afterward, we’ll have access to append() which we call to update py.sys.path:
One might think the append() function can be called directly from py.list, but that, too, fails:
Something to be aware of is that the import py.list.* command in MATLAB brought 12 new functions into our namespace:
Of the 12, all but mro() and pop() are existing MATLAB commands. Fortunately, MATLAB handles function overloading well. When given MATLAB-native variables, MATLAB invokes its own sort(), append(), and other functions. When these functions are given Python variables, MATLAB calls the Python versions instead.
6.7 Python Bridge Modules
Calls to Python functions from MATLAB can fail for a couple of reasons: there could be dynamic library load collisions that cause MATLAB to crash, or the Python objects visible from MATLAB have attributes or methods that cannot be seen in MATLAB.
The workaround for both cases is to write bridge modules that wrap problematic interfaces with ones MATLAB can handle. An example is the object returned by the weighted least squares function WLS() from the Python statsmodels module; MATLAB cannot access this object’s .predict() method (Section 11.8). To get around this, we need a small Python module with a function that takes inputs from MATLAB, calls WLS() and the solution’s .predict() method, then returns the answer in a dictionary that MATLAB can access.
Many examples of bridge modules appear in the recipes.
6.8 Debugging Python Code Called by MATLAB
Troubleshooting hybrid MATLAB/Python code can be a challenge because the MATLAB debugger won’t step into Python code. The only recourse to see what’s going on inside Python code is to instrument the code with print statements. Even that doesn’t always work though; sometimes, prints in Python do not appear in MATLAB’s console. If that happens with your code, you’ll need to write debug statements to a file instead. Here’s an example of that:
The file is opened in append mode with 'a' to accumulate repeated writes. Note also that we have to use the file handle’s .write() method rather than the print() function.
Logging can be automated somewhat with decorators or Python’s own trace module, but both of these methods have drawbacks over tailored print statements. Decorators wrap entire functions and so cannot provide details on the inner workings of functions they act on. The trace module has the opposite problem in that it reports on every line that runs—which can be a prodigious amount of output to wade through—but has no mechanism to show values of variables along the way.
Nonetheless, trace can provide useful insight when a Python function called from MATLAB goes completely off the rails. The following code shows how trace is used to follow execution of functions that compute terms of the Mandelbrot sequence (we’ll see this example again in Chapter 14):
Lines 7–31 are the unmodified functions. Tracing is enabled by importing the trace module (line 2) and calling the trace_do_work() function (lines 33–35) which is a wrapper to the regular entry point function, do_work(). First, we’ll do a regular, untraced run by calling do_work() directly:
Now we’ll call the wrapped function, trace_do_work(). It produces a huge amount of output, so before invoking it, enable MATLAB’s diary mode to save STDOUT to a file. Only a small portion of the thousands of lines of output is shown here:
6.9 Summary of Steps to Calling Python Code from MATLAB
- 1.
Implement a pure Python testbed of the code fragment you want to call from MATLAB if you’re calling many functions or manipulating several native Python variables within MATLAB. The pure Python solution will serve as a reference that can provide intermediate values and greatly simplify troubleshooting.
- 2.
Start MATLAB from the command line in a virtual environment configured properly for your versions of MATLAB and Python (Section 2.5.1).
- 3.
Augment the Python search path to include the directory containing your code (Section 6.6) if it isn’t visible from your work directory.
- 4.
Import the Python modules you want to call (Section 6.3).
- 5.
Convert, where necessary, input arguments to the Python function from MATLAB-native variables to Python-native variables (Section 6.5). Scalars and strings are usually exempt from this, except for cases where the Python function expects an integer. Numeric scalars in MATLAB default to being double-precision floating-point type, so these need to be converted to integers with int32() or int64(). The mat2py() function (Appendix D) can simplify such conversions.
- 6.
Call the desired Python function(s).
- 7.
Convert objects returned from Python functions to MATLAB-native variables, either by calling built-in MATLAB functions such as struct() or by using the generic py2mat() function (Appendix D).
- 8.
If the returned object does not include methods or attributes you need, write a bridge module with functions that explicitly call methods or fetch attributes that aren’t exposed to MATLAB.
The call-Python-from-MATLAB recipes that appear in subsequent chapters employ either a subset of these steps for simple cases or use all for the harder ones.
6.10 Call MATLAB from Python
The MathWorks also makes it possible to call MATLAB from Python. This is done with a Python module, matlab.engine, that users can optionally add to a given Python installation.
6.10.1 Install matlab.engine
To install the MATLAB Engine API for Python, first determine the Python environment where you want to add this module by listing your available environments. On Windows, using an Anaconda Prompt, it might look like this:
Next, start MATLAB and explicitly tell it the environment where you want to install the module by giving pyversion() the path to the Python executable for the desired environment. For the example of the matpy virtual environment listed earlier, that would be
Then install the module from MATLAB with
The two MATLAB commands earlier are operating system independent and work on Windows, macOS, and Linux.
6.10.2 Call Functions in a New MATLAB Session
The Python interface to MATLAB through its Engine API differs from MATLAB’s py module because matlab.engine needs to either start a MATLAB session or connect to an existing one. In contrast, the py interface from MATLAB to Python works by calling Python library functions; no running Python session is needed. Here, I’ll cover starting a new MATLAB session; connecting to an existing session will come in the following section.
A new MATLAB session can be created by calling start_matlab(). This function returns a handle to an engine instance from which all other MATLAB functions may be called:
Just as Python functions called from MATLAB return native Python variables, MATLAB functions called from Python return native MATLAB variables. Containers such as numeric arrays are easily converted to NumPy arrays simply by calling np.array() as done earlier.
6.10.3 Call Functions in an Existing MATLAB Session
Next, in Python, check if the engine can see any MATLAB sessions with find_matlab(). If exactly one engine is found, Python can attach to it by calling connect_matlab() without arguments. If multiple sessions are found, supply the name of the session of interest as an argument to connect_matlab():
MATLAB: | Python: |
---|---|
>> z = [ pi exp(1) ]; | In : import matlab.engine In : eng = matlab.engine.connect_matlab() In : eng.workspace['z'] Out: matlab.double([[3.141592653589793, 2.7182818284590455]]) |
Unfortunately, env.workspace lacks true dictionary functionality. As of MATLAB 2020b, one cannot call len(env.workspace) to count the number of known variables, iterate through variables with for var in env.workspace:, or access variable names through env.workspace.keys().
The env.workspace interface is bidirectional. Values created in Python will appear in the MATLAB workspace:
6.11 Other Mechanisms for MATLAB/Python Interaction
Older versions of MATLAB without the py module have less convenient vehicles for data exchange with Python. These include reading and writing .mat, JSON, XML, or plain text files or sending and receiving data over a network connection. MATLAB invocations of Python functions have to be done through system calls (Section 9.2) to stand-alone Python programs that implement the functions.
6.11.1 System Calls and File I/O
Calling Python functions directly from MATLAB is convenient and efficient, but is not the only way for the two languages to interact. Older versions of MATLAB without the py module obviously can’t use this method, and even newer versions of MATLAB may crash on calling Python functions that load conflicting shared libraries.
In these cases, the more primitive method of employing system calls and exchanging data via files can be employed. In Section 9.2, we’ll run other executables from MATLAB with its system() function. This simple example shows how MATLAB would run the Python program compute_stuff.py that exists in the MATLAB working directory:
result contains the combined lines of STDOUT and STDERR generated by compute_stuff.py, while the integer status has the program’s exit code—zero indicates success, while any non-zero value means the program either was unable to run or ended with an error.
Small amounts of data may be passed from MATLAB to Python via the command line, or environment variables, or the returned result. As the data volume or parsing complexity grows, file or network-based data exchange becomes more attractive. The most MATLAB-friendly file format is, of course, the .mat file; reading and writing these from Python is covered in Section 7.14.
6.11.1.1 JSON
The .mat file is just one of several formats that MATLAB and Python have in common. Others include HDF5, NetCDF4, XML, and JSON. The first two were covered in Sections 7.9 and 7.10. XML, while infinitely flexible, is commensurately tedious because one must laboriously define all entries. In contrast, JSON—JavaScript Object Notation—functions in MATLAB and Python automatically serialize and deserialize complex data structures to and from text strings. These strings can then either be written to and read from text files or sent and received over a network connection. Still, both XML and JSON are text formats and therefore become unwieldy for large numeric arrays.
6.11.1.2 MATLAB to Python via JSON
MATLAB (step 1): | Python (step 2): |
---|---|
>> b{1}.pos = [.5; -.3]; >> b{1}.vel = [2.7,3.8]; >> b{2}{1}.u = [0; 3]; >> b{2}{1}.v = { 'a '; 'bc' }; >> b{2}{2} = 22; >> jsonencode(b) '[{"pos":[0.5,-0.3], "vel":[2.7,3.8]},[{"u" :[0,3],"v":["a ","bc" ]},22]]' >> fh = fopen('b.json', 'w'); >> fprintf(fh, jsonencode(b)); >> fclose(fh); | In : import json In : fh = open('b.json') In : b = json.load(fh) In : fh.close() In : b Out: [ {'pos': [0.5, -0.3], 'vel': [2.7, 3.8]}, [{'u': [0, 3], 'v': ['a ', 'bc']}, 22]] |
6.11.1.3 Python to MATLAB via JSON
Python (step 1): | MATLAB (step 2): |
---|---|
In : b Out: [ {'pos': [0.5, -0.3], 'vel': [2.7, 3.8]}, [{'u': [0, 3], 'v': ['a ', 'bc']}, 22]] In : import json In : json.dump('b.json', b) | >> fh = fopen('b.json'); >> L = fgetl(fh); >> fclose(fh); >> b{1}.pos 0.5000 -0.3000 >> b{1}.vel 2.7000 3.8000 >> b{2}{1}.u 0 3 >> b{2}{1}.v {'a '} {'bc'} >> b{2}{2} 22 |
6.11.2 TCP/IP Exchange
MATLAB/Python network communication is described in Section 7.17.3. Data exchange over a network takes more coding effort than file-based exchange but offers higher I/O performance and does not consume file storage space. Also, the communicating programs must run simultaneously which complicates start-up and shutdown.
The code examples in Sections 7.17.3.1 through 7.17.3.4 sent integers and arrays of double-precision floats in native binary formats. Packing and unpacking each variable to and from binary buffers is tedious though. Another option is to serialize one or more variables into a commonly understood format—JSON, for example—and exchange that.