简体   繁体   English

从 .NET 调用 Python

[英]Call Python from .NET

I have some code written in Python which can not be transferred to a .NET language.我有一些用 Python 编写的代码,这些代码无法转换为 .NET 语言。 I need to call one of these functions from my .NET WinForms application.我需要从我的 .NET WinForms 应用程序中调用其中一个函数。

Now, I do it by starting the Python script as a separate process and pass parameters to it as command line arguments.现在,我将 Python 脚本作为一个单独的进程启动,并将参数作为命令行 arguments 传递给它。 It works, but I don't really like this solution.它有效,但我不太喜欢这种解决方案。 I'd like to improve it to a better one.我想把它改进成更好的。

Is there any better way to call a function of a .py script from a .NET application?有没有更好的方法从 .NET 应用程序调用.py脚本的 function ? What is the best way to do it?最好的方法是什么?

Note: IronPython is NOT an option for this Python script注意: IronPython 不是此 Python 脚本的选项

This might be a lot more work than launching the Python process, but here's an alternate solution.这可能比启动 Python 进程要多得多,但这里有一个替代解决方案。

You can embed Python into another program.您可以将 Python 嵌入到另一个程序中。 The API is for C and Interop from .NET will probably be a major pain. API 用于 C 和来自 .NET 的互操作可能会是一个主要的痛苦。 If you're into a bit of a safer way to handle the native Python API, you can look into Boost.Python , which, among its less advertised features, has support for embedding .如果您想以更安全的方式处理本机 Python API,您可以查看Boost.Python ,其中包括对嵌入的较少宣传的功能。

With these tools, you can write a C++ managed DLL that uses Boost.Python to load the Python interpreter and execute any Python script. With these tools, you can write a C++ managed DLL that uses Boost.Python to load the Python interpreter and execute any Python script. Thus, you can execute any Python code directly in the hosting process, eliminating the use of an external process and any form of IPC.因此,您可以直接在托管进程中执行任何 Python 代码,无需使用外部进程和任何形式的 IPC。

Edit : AFAIK, all you have to add to your installation procedure is the deployment of the Python DLL and Boost.Python DLL. Edit : AFAIK, all you have to add to your installation procedure is the deployment of the Python DLL and Boost.Python DLL.

I think you need to re-evaluate Carlos' answer.我认为您需要重新评估卡洛斯的答案。 See the section Implementing COM Objects with Python in Mark Hammond's book Python Programming on Win32.请参阅 Mark Hammond 的 Python Programming on Win32 中的使用 Python 实现 COM 对象部分。

You should be able to create a COM object, then have.Net interact with it.你应该可以创建一个COM object,然后让.Net与之交互。

From the book the following will create a COM server with a single method.从本书中,以下将使用单一方法创建 COM 服务器。

# SimpleCOMServer.py - A sample COM server - almost as small as they come!
# 
# We expose a single method in a Python COM object.
class PythonUtilities:
    _public_methods_ = [ 'SplitString' ]
    _reg_progid_ = "PythonDemos.Utilities"
    # NEVER copy the following ID 
    # Use "print pythoncom.CreateGuid()" to make a new one.
    _reg_clsid_ = "{41E24E95-D45A-11D2-852C-204C4F4F5020}"

    def SplitString(self, val, item=None):
        import string
        if item != None: item = str(item)
        return string.split(str(val), item)

# Add code so that when this script is run by
# Python.exe, it self-registers.
if __name__=='__main__':
    print "Registering COM server..."
    import win32com.server.register
    win32com.server.register.UseCommandLine(PythonUtilities)

The book goes on to say ".. you can do this by executing the code as a normal Python script. The easiest way to do this is to open the source file in PythonWin and use the Run command from the File menu. "这本书继续说“..你可以通过执行代码作为普通的 Python 脚本来做到这一点。最简单的方法是在 PythonWin 中打开源文件并使用文件菜单中的运行命令。“

I think you need the ActivePython distribution from Activestate to do it.我认为您需要 Activestate 的 ActivePython 发行版才能做到这一点。

See this question Consuming Python COM Server from .NET 从 .NET看到这个问题

Besides the COM option, you could make your Python script instantiate a xmlrpc server - it is quite transparent and you never have to deal with "xml" on your own code.除了 COM 选项之外,您还可以让您的 Python 脚本实例化一个 xmlrpc 服务器 - 它非常透明,您永远不必在自己的代码中处理“xml”。

Then, on .net side, you simply connect to your python app via xmlrpc - if there is no suitable way to do that in C#, just write a client function in IronPython. Then, on .net side, you simply connect to your python app via xmlrpc - if there is no suitable way to do that in C#, just write a client function in IronPython.

The SimpleXMLRPCServer example on Python documentation is enough for that: Python 文档上的 SimpleXMLRPCServer 示例就足够了:

http://docs.python.org/library/simplexmlrpcserver.html http://docs.python.org/library/simplexmlrpcserver.html

PythonNet should help with this one. PythonNet应该对此有所帮助。 It enables you to call python code from C#.它使您能够从 C# 调用 python 代码。

A cleaner way is to expose the python script via a Flask REST API and consume that from your .NET Application. A cleaner way is to expose the python script via a Flask REST API and consume that from your .NET Application. Don't forget to put proper authentication in place.不要忘记进行适当的身份验证

It works, but I don't really like this solution, I'd like to improve it to a better one.它有效,但我不太喜欢这个解决方案,我想将它改进为更好的解决方案。

No, AFAIK there isn't a better solution, especially if IronPython is a no-no for you.不,AFAIK 没有更好的解决方案,特别是如果 IronPython 不适合您。 So you could still keep this as a temporary workaround while waiting for the script to be migrated to .NET or until you find that someone already wrote a library on .NET that provides you with similar functionality.因此,在等待脚本迁移到 .NET 或发现有人已经在 .NET 上编写了为您提供类似功能的库之前,您仍然可以将此作为临时解决方法。

Create a COM.dll from a.py script and use Interop in your .NET code.从 a.py 脚本创建 COM.dll 并在 .NET 代码中使用互操作。 Have a look here: http://docs.python.org/faq/windows.html看看这里: http://docs.python.org/faq/windows.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM