Написание расширения Python в Go (Golang)

В настоящее время я использую Cython, чтобы связать C и Python и получить ускорение в медленных битах кода Python. Тем не менее, я хотел бы использовать горутины для реализации очень медленного (и очень параллелизуемого) фрагмента кода, но он должен вызываться из python. (я уже видел этот вопрос)

Я (вроде как) рад использовать C (или Cython) для настройки структур данных и т. д., если это необходимо, но избегать этого дополнительного слоя было бы хорошо с точки зрения исправления/предотвращения ошибок.

Каков самый простой способ сделать это без необходимости изобретать колеса?


person tehwalrus    schedule 15.09.2012    source источник


Ответы (4)


Обновление 2015: возможно начиная с Go 1.5 https://blog.filippo.io/building-python-modules-with-go-1-5/

с Go 1.5 вы можете создавать объекты .so и импортировать их как модули Python, запуская код Go (вместо C) непосредственно из Python.

См. также https://github.com/go-python/gopy.

gopy генерирует модуль расширения CPython из пакета go.

person Colonel Panic    schedule 27.09.2015
comment
Проект github.com/go-python/gopy делает это абсурдно простым, создавая для вас всю необходимую сантехнику, о которой упоминается в блоге. - person Chris Townsend; 10.11.2015
comment
gopy в настоящее время не совместим с Go›=1.6, так что это было недолго. - person mattmc3; 03.08.2016
comment
gopy был обновлен для поддержки новых версий Go. Он использует опцию сборки c-shared и проект pybindgen. - person dre-hh; 29.05.2020

К сожалению, в настоящее время это невозможно. Go может запускать код C (и этот код C может затем вызывать Go), но main должна быть в Go, чтобы среда выполнения Go могла все настроить.

person Russ Amos    schedule 16.09.2012
comment
Возможно, тогда можно вызвать go в отдельном процессе через xmlrpc? - person jsbueno; 16.09.2012
comment
Спасибо, это в значительной степени ставит идею в постель. Таким образом, единственный способ сделать это — использовать что-то вроде python_part_1 | go_program | python_part_2 с использованием каналов (или промежуточных файлов, или XMLRPC) для передачи данных? - person tehwalrus; 16.09.2012
comment
Вы можете использовать сокеты для выполнения RPC. - person Vladimir Matveev; 16.09.2012
comment
Встроить Python в программу на C довольно просто. Интересно, сможете ли вы затем встроить эту программу C в программу Go... Взаимодействие Python и Go должно проходить через уровень C. - person Nick Craig-Wood; 16.09.2012
comment
Для связи между процессами Go и Python вы можете запустить программу Python в другом процессе и использовать stdin, stdout для связи между процессами (пакет os/exec). Для этого JSON будет лучше, чем XMLRPC, потому что в настоящее время с XML немного сложнее работать в Go, чем с JSON. - person Matt; 17.09.2012
comment
Если вы используете канал stdin/out/err для связи, лучше не использовать какой-либо текстовый формат. Используйте msgpack или что-то более легкое, или даже просто сериализуйте свои структуры по конвейеру. В Python есть пакет/распаковка, а в Go для этого есть кодировка/бинарный код. - person fiorix; 18.04.2014
comment
Теперь это возможно с Go 1.5 — рабочие примеры см. на github.com/jbuberel/buildmodeshared. - person Jason Buberel; 23.08.2015

Я написал расширение для setuptools, которое позволяет вам писать расширения cpython, взаимодействующие с go: https://github.com/asottile/setuptools-golang

Здесь есть пара примеров расширений:

Удобно то, что их можно установить так же, как и любой другой пакет pip, и они поддерживают как cpython, так и pypy.

PEP 513 Многие колеса Linux1 также могут быть созданы для предоставления готовых колес через инструмент setuptools-golang-build-manylinux-wheels.

Подход почти идентичен подходу в ответе @ColonelPanic, но использует некоторые дополнительные приемы для включения совместимости python2 + python3.

person Anthony Sottile    schedule 01.02.2017

Существует пакет go-python, который поможет вам писать расширения Python в Go:

этот пакет предоставляет исполняемый файл «go-python», который просто загружает «python», а затем вызывает python.Py_Main(os.Args). рациональным является то, что в таком исполняемом файле расширения на основе go для C-Python было бы проще реализовать (поскольку это обычно означает вызов go из C через некоторые довольно запутанные переходы функций)

person uriel    schedule 17.09.2012
comment
Из того, что я читал, go-python помогает вам вызывать Python из Go, а не наоборот. - person zneak; 17.09.2012
comment
Это то, что я видел и отбросил именно потому, что, как выразился @zneak, все было наоборот. - person tehwalrus; 17.09.2012
comment
Я добавил цитату непосредственно из readme go-python, которая объясняет, как использовать его для создания расширений python. - person uriel; 20.09.2012