如果我在Python中创建一个包,那么另一个Python用户可以导入该包并与之接口。
如何创建一个包,以便其他用户调用该库的语言无关紧要?
我可以指定输入和输出文件格式,以便另一种语言可以通过仅提供输入文件和读取输出文件来与我的Python代码进行交互。但是,创建输入和输出文件在计算上非常昂贵。有更简单的解决方案吗?
答案 0 :(得分:7)
如果您希望其他语言能够直接使用您的库 (不使用任何类型的远程服务或IPC的东西,这是一个完全不同的鱼),您需要写语言绑定,意味着他们在目标语言中调用了一个层来调用你的包。有许多工具包可用于创建它,但如果您希望能够从更高级别的脚本语言(如Python)调用C或C ++库,通常会执行此类操作。例如,在C中存在SWIG项目,以帮助从Python,PHP,Ruby等调用C语言。
这个页面会给你一堆介绍链接,说实话,这是一个很难和很难的话题。我自己只用C到Python做过。 https://wiki.python.org/moin/IntegratingPythonWithOtherLanguages
答案 1 :(得分:3)
通过像http这样的通用协议提供API,并使用通用的调用和响应格式(如REST服务)可能就是您想要做的。有很多资源可以帮助您开始使用python编写REST Web服务,如下所示:
https://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask
如果你想让它保持在本地机器上,并提供你在本地程序中使用的python功能,python.org在这里给你一个入门读物:
答案 2 :(得分:3)
在一般情况下,两种不同的语言不能生活在同一个过程中。所以你必须通过进程间通信(IPC)让一种语言调用另一种语言。
最简单且通常有效的方法是通过calee" library"的输入/输出。它通常具有某种序列化开销,但在典型的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()
答案 3 :(得分:2)
@ bluprince13没有这样的方法可以从每种语言调用库,至少不能直接使用包装器代码。 Windows上的COM接口已经关闭,然后可以被大多数程序(例如Excel,MATLAB,JAVA)导入,但这是一个巨大的痛苦。
当你说读/写是一项昂贵的操作时,你不能使用Pandas read_csv
和to_csv
函数 - 它们是超快速(C ++)实现。更快速的是二进制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(已编译),您可以在本帖末尾的DropBox链接中使用您在.py
表单中创建的任何Python函数(embedpython.exe
)以及所有文件在那里的zip中,这可能是你最好,最简单,最快的路径 - 源代码/用法参考:Embedded Python does not work pointing to Python35.zip with NumPy - how to fix? FAR是让你的代码在任何系统上兼容,并在你的Python之间切换的最简单方法脚本很简单(当你调用不同的库时,整个包必须在子文件夹中可用)。在Anaconda Python安装中,文件将位于相应的已安装包文件夹中,通常为C:\Anaconda3\Lib\site-packages\ [packageName] \
;典型的Python安装位于C:\Python\Lib\site-packages\ [packageName] \
)。否则,从安装了Python的命令提示符cd\
开始,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)
C ++:How to call an external program with parameters? .NET C#:How to pass parameters to an exe?如您所见,列表一直在继续......几乎任何语言都可以调用EXE文件。当然,您需要最高性能,但要获得所有语言的兼容性,您必须以某种方式妥协。但是使用上述建议,只要.py
函数得到优化,您的性能仍然会很好。
让每个人的生活更轻松这里是编译版x64 Python 3.5 Windows NumPy SciPy和Pandas英特尔MKL包括:https://www.dropbox.com/sh/2smbgen2i9ilf2e/AADI8A3pCAFU-EqNLTbOiUwJa?dl=0
如果您是Windows用户,请下载以上内容并将您的.py
脚本放在您要分发的位置,以及\ extension_modules \ [package_name]中的依赖库,您的代码将是没有麻烦。您没有指定是否在Linux下使用它,因此我的Windows解决方案是您“使用任何语言”的问题,需要对其他编程语言的了解最少。
答案 4 :(得分:2)
您可以使用Cython to relatively easily extend your python code so that it can be compiled as a C library。大多数情况下,这只涉及将def
关键字替换为cdef public
,以用于要公开的函数,并注释变量类型。
以下是此类Cython代码的示例:
cdef public void grail(int num):
printf("Ready the holy hand grenade and count to %i", num)
此时,许多语言都有Foreign Function Interfaces (FFI)到C代码。
答案 5 :(得分:1)
正如已经多次提到的那样 - 其中一种方法是创建REST API并通过HTTP发送输入和输出。
但是,还有另一种选择更为复杂。您可以使用CORBA(公共对象请求代理体系结构)。在python omniORB
中有一个CORBA实现。 CORBA允许在用各种语言编写的应用程序之间进行接口。
在网上使用CORBA和python有很多例子。
答案 6 :(得分:1)
与Nurzhan上面提到的关于CORBA的类似精神,您可以使用OPC UA:https://en.m.wikipedia.org/wiki/OPC_Unified_Architecture
这是一种面向通过服务器到客户端通信进行设备控制的架构,但可能适合您的需求。在我的工作中,我们使用了许可的C / C ++(统一自动化和Java sdks(prosys),探索了Python选项以及来自PLC的嵌入式解决方案,并且可以很好地进行跨层通信。
Web中有几个用于Python UA的OPC UA的开源项目,例如: freeopcua。