IronPython与Python .NET的比较
我想从Python代码中访问一些用C#写的.NET程序集。
经过一些研究,我发现我有两个选择:
- IronPython,它自带了与.NET接口的支持
- 使用带有Python .NET包的Python
这两种方案各有什么优缺点呢?
10 个回答
大多数科学和数值计算的Python库,比如numpy、scipy、matplotlib、pandas、cython等,主要是基于CPython这个C语言的接口来工作的。所以在这种情况下,最好的选择就是使用pythonnet(还有其他名字,比如Python.NET和Python for .NET)。
对于CPython的图形用户界面(GUI)绑定,比如WxWidgets、PyQt/PySide、GTK、Kivy等情况也是一样,虽然pythonnet和IronPython都可以使用WPF和WinForms。
最后,IronPython目前还不完全支持Python 3。
在我同意Reed Copsey和Alex Martelli的回答的同时,我想再提到一个不同之处——全局解释器锁(GIL)。IronPython没有GIL的限制,而CPython则有。因此,对于那些在某些多核场景下GIL成为瓶颈的应用,IronPython相比Python.NET有优势。
根据Python.NET的文档:
嵌入者的重要提示: Python 不是自由线程的,它使用全局解释器锁来确保 多线程应用能够安全地与Python 解释器互动。关于这方面的信息 可以在Python C API文档中找到,网址是
www.python.org
。在将Python嵌入到一个托管应用程序时,你需要像在C或C++应用程序中嵌入Python时一样管理GIL。
在与任何由
Python.Runtime
命名空间提供的对象或API互动之前,调用代码 必须通过调用PythonEngine.AcquireLock
方法来获取Python的全局 解释器锁。唯一的例外是PythonEngine.Initialize
方法,可以在启动时调用,而不需要 获取GIL。当使用完Python API后, 托管代码必须调用相应的
PythonEngine.ReleaseLock
来释放 GIL,以便其他线程可以使用 Python。
AcquireLock
和ReleaseLock
方法是对Python API中 不受管理的PyGILState_Ensure
和PyGILState_Release
函数的简单封装,相关的文档同样适用于 托管版本。
另一个问题是IDE的支持。目前,CPython的IDE支持可能比IronPython更好——所以这可能是选择其中一个的一个因素。
如果你想主要基于 .NET 框架来写代码,我强烈推荐使用 IronPython,而不是 Python.NET。IronPython 基本上就是原生的 .NET,所以在和其他 .NET 语言结合时,它的表现非常好。
如果你只是想把 .NET 的一两个组件整合进一个普通的 Python 应用,Python.NET 也不错。
使用 IronPython 时有一些明显的区别,但大多数都比较细微。Python.NET 使用的是标准的 CPython 运行环境,所以这个维基页面讨论了这两种实现之间的差异。最大的区别在于异常处理的成本,所以一些标准的 Python 库在 IronPython 中的表现可能不太好,因为它们的实现方式不同。