Как создать независимую от языка библиотеку с помощью Python?

Если я создам пакет в Python, другой пользователь Python может импортировать этот пакет и интерфейс с ним.

Как создать пакет, чтобы не иметь значения, с какого языка вызывается другой пользователь?

Я могу указать форматы входных и выходных файлов, чтобы другой язык мог взаимодействовать с моим кодом Python, просто предоставляя входные файлы и считывая выходные файлы. Однако создание входных и выходных файлов очень дорогостоящим способом. Есть ли более легкое решение?

Ответ 1

@bluprince13 Нет такого способа, чтобы библиотека могла быть выведена из любого языка, по крайней мере, напрямую без кода обертки. COM-интерфейс в Windows близок, который затем может быть импортирован большинством программ (таких как Excel, MATLAB, JAVA), но это огромная боль, чтобы писать.

Когда вы говорите, что чтение/запись - дорогостоящая операция, вы не должны использовать функции Pandas read_csv и to_csv - они быстро реализуются (С++). Еще быстрее - двоичные файлы HDF5, хотя для большинства пользователей сложнее работать http://pandas.pydata.org/pandas-docs/version/0.20/io.html read_hdf и to_hdf, который поддерживается большим количеством языков https://en.wikipedia.org/wiki/Hierarchical_Data_Format. Использование входных и выходных файлов сделает вашу программу более переносимой.

Используя встроенный Python (скомпилированный), вы можете просто использовать любые функции Python, которые вы создали, в форме .py (embedpython.exe на моей ссылке DropBox в конце этого сообщения вместе со всеми файлами в zip там), который, вероятно, является вашим лучшим, простым и быстрым маршрутом для ссылки на исходный код/​​использование: Встраиваемый Python не работает, указывая на Python35.zip с NumPy - как исправить? Именно FAR - это самый простой способ получить код в любой системе, и смена между вашими скриптами Python проста (при вызове разных библиотек все пакеты должны быть доступны во вложенной папке). В установке Anaconda Python файлы будут находиться в папке соответствующих установленных пакетов, обычно C:\Anaconda3\Lib\site-packages\ [packageName] \; типичные установки Python расположены в C:\Python\Lib\site-packages\ [packageName] \). В противном случае из командной строки cd\, где установлен Python, тогда dir /s site-packages найдет местоположение. Затем вы поместите весь каталог установки для каждого пакета в каталог "extension_modules". Таким образом, он выглядит как extension_modules\numpy\, extension_modules\pandas\ и все библиотеки, которые вы импортируете (вместе с библиотеками, на которые зависят пакеты).

Ниже приведены примеры вызова соответствующего языка с помощью EXE: JAVA: Process process = new ProcessBuilder("C:\\PathToExe\\embedpython.exe","pyscript","pyfunction","input_param1","input_param2").start(); MATLAB: system('"C:\PathToExe\embedpython.exe" pyscript pyfunction input_param1 input_param2'); VBA: Call Shell("C:\PathToExe\embedpython.exe" "pyscript" "pyfunction" "param1" "param2", vbNormalFocus) С++: Как вызвать внешнюю программу с параметрами?.NET С#: Как передать параметры в exe?, как вы видите, список можно продолжать и продолжать... в значительной степени любой язык может вызывать EXE файл. Конечно, вы хотите максимальной производительности, но чтобы получить совместимость на всех языках, которые вы должны компрометировать в некотором роде. Но, используя приведенные выше рекомендации, ваша производительность должна быть великолепной при оптимизации функций .py.

Сделать жизнь проще здесь скомпилированной версией x64 Python 3.5 Windows NumPy SciPy и Pandas Intel MKL в комплекте: https://www.dropbox.com/sh/2smbgen2i9ilf2e/AADI8A3pCAFU-EqNLTbOiUwJa?dl=0 p >

Если вы пользователь Windows, загрузите приведенное выше и поместите свой .py script там, где вы хотите распространять вместе с зависимыми библиотеками в\extension_modules\[имя_пакета], и вы будете использовать код бегать без хлопот. Вы не указали, следует ли это использовать в Linux, чтобы мое решение Windows на вопрос "использовать с любого языка", требующее наименьшего знания других языков программирования.

Ответ 2

Если вы хотите, чтобы другой язык имел возможность напрямую использовать вашу библиотеку (не используя какой-либо удаленный сервис или материал IPC, который представляет собой совершенно другой чайник), вам нужно написать для него языковые привязки, то есть есть которые они вызывают на целевом языке, который вызывает ваш пакет под капотом. Существуют различные инструментальные средства для создания этого, но обычно это то, что вы делаете, если хотите, чтобы вы могли называть C или С++ библиотеку с языка сценариев более высокого уровня, такого как Python. Например, в C существует проект SWIG, который позволяет вызвать C из Python, PHP, Ruby и т.д.

Эта страница даст вам кучу интро-ссылок, это большая и трудная тема, если честно. Я сделал это только от C до Python. https://wiki.python.org/moin/IntegratingPythonWithOtherLanguages

Ответ 3

Предоставление API через общий протокол, такой как http, и с общим форматом для вызовов и ответов - например, служба REST - это, вероятно, то, что вы хотите сделать. Есть так много ресурсов, которые помогут вам начать писать веб-службу REST с помощью python, например:

https://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask

Если вы хотите сохранить его локальным для машины и предоставить свою функциональность python для локального использования в программах, python.org дает вам праймер здесь:

https://docs.python.org/2/extending/embedding.html

Ответ 4

В общем случае два разных языка не могут жить в одном и том же процессе. Таким образом, вы должны сделать один язык вызовом другого межпроцессного взаимодействия (IPC).

Самый простой и обычно эффективный способ сделать это - через ввод/вывод библиотеки "calee". Обычно это имеет некоторые из сериализационных издержек, но в типичном взаимодействии с Matlab/python это не должно быть заметно.

В этой конфигурации самая медленная часть - это запуск процесса python, который может быть подавлен, поддерживая один и тот же процесс между двумя вызовами.

Вот пример ipc между основной программой в python (но может быть написан на любом языке) и библиотекой в ​​python с использованием stdin/stdout и json в качестве сериализации


#main program in foreign language

import mylibwrapper

print(mylibwrapper.call("add",[1,2]))

mylibwrapper.exit()

#mylibwrapper.py supposed written in foreign language
import subprocess
import json

process = subprocess.Popen([
    "python3",
     "mylib.py"],
    stdin = subprocess.PIPE,
    stdout = subprocess.PIPE,
    encoding = "utf8")

def call(name,args):
  process.stdin.write(json.dumps([name,args]))
  process.stdin.write("\n")
  process.stdin.flush()
  result = process.stdout.readline()
  return(result)
def exit():
  process.terminate()

#mylib.py

import json, sys

def add(arg1,arg2):
  return arg1 + arg2

if __name__ == "__main__":

  for line in sys.stdin:
    name, args = json.loads(line)
    function = { "add" : add }[name]
    sys.stdout.write(json.dumps(function( *args)))
    sys.stdout.write("\n")
    sys.stdout.flush()

Ответ 5

Вы можете использовать Cython относительно легко расширить свой код на Python, чтобы он мог быть скомпилирован как библиотека C. В основном, это просто связано с заменой ключевого слова def на cdef public для функций, которые вы хотите открыть, и аннотирования типов переменных.

Вот пример такого Cython-кода:

cdef public void grail(int num):
    printf("Ready the holy hand grenade and count to %i", num) 

В этот момент на многих языках Интерфейсы внешних функций (FFI) отображаются на C-коде.

Ответ 6

Как уже упоминалось много раз - одним из способов является создание REST API и отправка ввода и вывода по HTTP.

Однако есть еще один вариант, который является более сложным. Вы можете использовать CORBA (Common Broker Architecture). Существует реализация CORBA в python omniORB. CORBA позволяет взаимодействовать между приложениями, написанными на разных языках.

Существует ряд примеров использования CORBA с python в Интернете.

Ответ 7

В том же духе, что и Нуржан упоминает выше относительно CORBA, вы можете использовать OPC UA: https://en.m.wikipedia.org/wiki/OPC_Unified_Architecture

Это архитектура, ориентированная на управление устройством через взаимодействие между сервером и клиентом, но может удовлетворить ваши потребности. В моей работе мы использовали лицензированные C/С++ (унифицированная автоматизация и Java sdks (prosys), изученные варианты Python, а также встроенные решения от ПЛК и межплатформенная связь хорошо работают.

Существует несколько проектов с открытым исходным кодом для OPC UA в Python в сети, например. freeopcua.