Python is Not Okay: How to plug other languages into Python
When Python doesn’t cut it, you can plug other languages into Python.
by Vincent Wang
Python has a neat, slightly hidden feature built into it — it can interface with other languages. Basically, in addition to normal Python code, you can also import C/C++ packages, Java modules, and more! Let’s break down the ways you can have Python interface with other languages:
Python and C/C++
There’s basically 3 ways to have Python interface with C/C++:
- Manually writing Python bindings (powerful but complicated)
- Using CTypes (easy but slow)
- Cython (fast)
- SWIG (Generic)
Let’s break it down:
- Python has a good guide for how to manually write C extensions for your Python programs. This is the option that allows you the most control over how Python interfaces with C and the one you should choose if you know what you’re doing. However, the guide is fairly long and complicated and there’s quite a bit of setup to do to get it working. If you don’t have insane speed requirements and want it to just work, this solution’s probably not for you.
- CTypes is a Python builtin library that can load DLLs (or SOs, they both work). This is by far the easiest way, with next to no setup required; all you need to do is
import ctypes
and thencdll.LoadLibrary("/path/to/dll").
But there’s a caveat to this method; Python converts datatypes to and from C behind the scenes, which can often lead to slowdowns. If you only want convenience and compatibility and don’t care too much about speed, this is for you; if you need your code to run fast, check out Cython. - Cython is a Python extension best known for making your Python code run fast with static typing, but it can also import C/C++ code. Cython has decent documentation on how to set up a wrapper; while it is more work than good old CTypes, it’s definitely way faster.
- SWIG is a C/C++ wrapper generator. It does a lot more than just Python — it generates C/C++ wrappers for everything from C# to Tcl. You can follow their tutorial to generate a wrapped library for Python.
Python and Java
Like C++, there are multiple ways to interface Python and Java. Let’s list the options:
- Jython is a special variant of Python that’s designed to run on the JVM; that is, the Python interpreter and your Python code runs in the same environment as Java programs. This comes with the added benefit of Jython being able to import Java packages into your Python script. There’s no extra work involved; you can import Java packages the same way you would import Python ones (e.g.
from java.util import Math
). One of the disadvantages to this approach is since Jython is a variant from regular CPython, not all CPython packages may work. - VOC is a compiler that compiles Python directly into Java class files. This means your Python code is turned directly into Java code; you don’t need a separate interpreter. It’s just as simple to use as Jython; just
from w.x import y
(see example above). However, VOC is still in early development, it’s only designed to match Python 3.4 features, and it doesn’t match as many Python features as Jython. Your mileage may vary. Use at your own risk.
Python and Javascript
OK, there’s actually multiple ways to do all of these. Here’s yet another list:
- PyV8 is a port of Google’s Javascript interpreter wrapped in Python. You can run any valid Javascript code that doesn’t depend on the DOM/an HTML website; Andrew Wilkinson has an excellent guide on integration here. For those of you who don’t want to open another browser tab, here’s a breakdown of how to use it:
1.pip3 install --user pyv8
2. Open a file
3. Paste these 5 lines:
import pyv8
ctxt = pyv8.JSContext()
ctxt.enter()
ctxt.eval(open(“library.js”).read()) # Where library.js is your JS library
value = ctxt.eval(“library_function({})”.format(param)) # Obviously, edit to your needs
2. Transcrypt is a Python to Javascript compiler. You can use Node.js libraries the same way you’d normally use them — a quick http = require('http')
would import the HTTP library, for instance. Once you’re done, you can compile your Python code to JS using transcrypt -b -p .none file.py
and then run it using node file.js.
You can also use them as regular client-side JS connected to HTML; further documentation is here. NOTE: in my testing, I was unable to get Transcrypt’s Node.js export working. This may only be a temporary bug, but if you plan to use Node.js or server-side Javascript, you may want to use XML-RPC below.
Python and Go
You can compile Go code to C. Once you’ve done that, it’s a simple matter of following one of the methods listed up above. Here’s how to do it:
- Run
go build -buildmode=c-shared -o hello.so name_of_file.go
(you can replace name_of_file.go with a directory to compile the whole directory) - Use any of the methods listed under “Python and C”.
- Profit!
Other Methods
In addition to the language-specific ways listed above, there are also methods that should work on any language and methods that work on other languages. Here’s a list:
- XML-RPC: XML-RPC is a protocol designed to let programs call functions using XML payloads. Any language with support for the XML-RPC protocol should be able to use this method; examples are Python, Java, Go, and Perl. Since implementations and libraries are language-specific, I can’t go into too much detail here; a place to start would be this probably decades-old document. The basic architecture is server-client; Python is the client (it gets the result) and the language you want to integrate is the server (it receives the request and returns a result).
- Python’s own documentation has a great list of projects that can help you integrate Python with other languages. Some of these might be old/deprecated/unstable, so use at your own risk!
Conclusion
Python is an excellent language on its own, but where it really excels is as a “glue” language. Because of its ability to interface with many languages, such as C++ and Java, it’s a great language for writing projects that may involve several programming languages.