IronPython与Python .NET的比较

95

我希望从Python代码中访问一些用C#编写的.NET程序集。

经过一番调查,我有两个选择:

这两种解决方案之间有什么权衡之处?

10个回答

76

如果你想主要使用.NET框架编写代码,我强烈推荐使用IronPython而不是Python.NET。IronPython几乎是本地的.NET - 因此在与其他.NET语言集成时表现出色。

如果您只想将一个或两个组件从.NET集成到标准Python应用程序中,则Python.NET很好。

使用IronPython时有值得注意的差异-但大多数差异都相当微妙。Python.NET使用标准的CPython运行时,因此这个维基页面讨论了两种实现之间的差异。最大的差异在于异常的成本-因此由于其实现方式,一些标准的Python库在IronPython中的性能表现不佳。


13
IronPython现在有“轻量级”异常,速度要快得多。从PyBench的TryRaiseExcept测试,原本慢了60倍,现在只慢了1.6倍。WithRaiseExcept仍然很慢,但比以前快了4倍。对于大多数其他测试,IPy实际上更快。IronPython 2.7与CPython 2.7性能比较(完整的基准测试列表)。 - Athari

30
虽然我认同Reed Copsey和Alex Martelli所提供的答案,但我还想指出进一步的区别-全局解释器锁(Global Interpreter Lock,GIL)。虽然IronPython没有GIL的限制,CPython有-GIL因此对于那些GIL成为瓶颈的应用程序,比如在某些多核场景中,IronPython比Python.NET更具优势。
来自Python.NET文档:
重要提示:Python不是自由线程的,并使用全局解释器锁来允许多线程应用程序与Python解释器安全交互。关于这方面的更多信息可在python.org网站上的Python C API文档中找到。
当在托管应用程序中嵌入Python时,您必须像在C或C ++应用程序中嵌入Python时一样管理GIL。
在调用代码通过调用PythonEngine.AcquireLock方法获得Python全局解释器锁之前,先与Python.Runtime命名空间提供的任何对象或API进行交互。唯一的例外是可以在启动时调用PythonEngine.Initialize方法而不必获取GIL。
在完成使用Python API之后,托管代码必须调用相应的PythonEngine.ReleaseLock以释放GIL并允许其他线程使用Python。
AcquireLock和ReleaseLock方法是未经处理的PyGILState_Ensure和PyGILState_Release函数的薄包装器,并且适用于托管版本的那些API的文档。

另一个问题是IDE支持。目前,与IronPython相比,CPython可能拥有更好的IDE支持-因此这可能是选择其中之一的因素。


4
PyDev Eclipse 插件支持 CPython、IronPython 和 Jython。 - Knut Eldhuset
3
@Knut:没错,但我撰写这个答案时情况不是这样的。 - Vinay Sajip

20

大多数依赖于CPython C-API的科学和数值Python库(如numpy、scipy、matplotlib、pandas、cython等)主要在CPython下工作,因此在这种情况下,您最好使用pythonnet(其他名称为Python.NET和Python for .NET)。

同样适用于CPython GUI绑定,例如WxWidgets、PyQt/PySide、GTK、Kivy等,尽管pythonnet和IronPython都可以使用WPF和WinForms。

最后,IronPython尚未完全支持Python 3。


9
IronPython是“.NET本地化”的 - 如果您想要完全将Python代码与.NET完全集成,则最好使用IronPython;Python.NET适用于Classic Python,因此它使您的Python代码与.NET保持一定距离。 (请注意,使用{{link1:this code}},您实际上可以从您的IronPython代码中使用为CPython编写的扩展,因此这不再是一个歧视条件)。

6

IronPython源自微软,所以我会凭直觉首选它,因为你必须假定它会与其他微软技术更加兼容。


1
我对此表示怀疑,因为它不是 VS20xx 的一部分。 - Peter

5

关于2016年的情况。

在我公司,我们使用了IronPython,但我们对其性能不满意(主要是内存使用 - 垃圾回收器太慢),因此我们决定切换到标准Python,并使用Zeroce-s ICE将其与.Net集成。


我很惊讶为什么选择在不同进程之间使用RPC来提高性能。最有可能的是,在同一进程中使用CPython + .NET并使用pythonnet会比这种方法更快。至于Zeroce ICE,请注意它是GPL许可证,因此不太适合商业应用。 - denfromufa
一个有趣的解决方案,谢谢。至于许可证,ICE 有商业选项:https://zeroc.com/licensing - Atorian

4

目前IronPython不支持Python 3.6(仅支持2.7)。

IronPython 3中,"尚未提供IronPython 3的版本."


他们目前正在开发v3,但进展缓慢:https://github.com/IronLanguages/ironpython3 - LimpingNinja

2
  1. IronPython类似于C#,因为它依赖于静态预编译库,但与C#不同的是它是一种动态语言。

  2. CPython类似于C++,就像IronPython是一种动态语言,并且可以访问动态库,这意味着被迫编写所有内容。

  3. 在某些方面,IronPython比C#更快,但不如CPython快,然而你可以将IronPython链接到任何语言,以克服问题,但同样也可以使用CPython。

无论你选择什么,这都是一个有趣、简单和强大的语言!


1
Iron Python基本上是带有集成.NET支持的Python 2.7,它可能永远不会支持Python 3。它失去了C和Python库的优势,但在另一方面可以访问.NET并且可以通过C#进行扩展。因此,如果您已经使用C#,那么Iron Python是一个额外的优势。

-1

我主要偏爱Python用于.NET,因为IronPython被编译为托管代码,很容易被反编译(这是我最讨厌的),但是使用py2exe或pyinstaller可以将Python与NET模块编译为非托管应用程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接