How to Call Python from Go (and Vice Versa)

Call Python from Go using os/exec or cgo, and call Go from Python using subprocess or ctypes for shared libraries.

Use os/exec to run Python from Go, or cgo to embed Python directly in Go; conversely, use subprocess in Python to run Go binaries. For Go calling Python via subprocess:

package main

import (
	"fmt"
	"os/exec"
)

func main() {
	cmd := exec.Command("python3", "script.py")
	output, err := cmd.CombinedOutput()
	if err != nil {
		panic(err)
	}
	fmt.Println(string(output))
}

For Python calling Go via subprocess:

import subprocess

result = subprocess.run(["./my-go-binary"], capture_output=True, text=True)
print(result.stdout)

For Go calling Python via cgo (requires cgo enabled and Python dev headers):

package main

/*
#include <Python.h>
*/
import "C"
import (
	"fmt"
	"unsafe"
)

func main() {
	C.Py_Initialize()
	defer C.Py_Finalize()

	code := C.CString("print('Hello from Python')")
	defer C.free(unsafe.Pointer(code))

	if C.PyRun_SimpleString(code) != 0 {
		fmt.Println("Python error")
	}
}

For Python calling Go via ctypes (requires compiled Go shared library):

import ctypes

lib = ctypes.CDLL("./libmygo.so")
lib.my_go_function()