28 十一月 2024

将C#库集成到Python中:包装与代码转换

开发人员可能会遇到这样的情况:他们已经有一个建立良好并经过测试的 C# 库,其功能表现出色。然而,他们的客户在 Python 环境中工作,需要访问该库的功能。在这种情况下,开发人员需要找到集成方法,使 C# 库可以在 Python 中使用。在本文中,我们将探讨解决此任务的两种方法——包装和代码转换,并讨论它们的优缺点。这将帮助您选择最合适的方法,并确保轻松访问您在 Python 中的 C# 库的功能。

将 C# 代码集成到 Python 中的方法

如前所述,有两种将 C# 代码集成到 Python 环境中的主要方法:包装和代码转换。

  • 包装 涉及使用专门的库和工具创建一个将 C# 代码与 Python 连接的接口。这允许直接从 Python 调用 C# 的函数和方法。当您需要保留原始 C# 代码而不进行更改并快速将其集成到 Python 中时,此方法非常方便。
  • 代码转换,另一方面,涉及将 C# 代码转换为其等效的 Python 代码。此方法需要大量工作,因为不仅需要重写代码,还需要适应 Python 生态系统的具体情况。

让我们仔细看看这两种方法。

将 C# 代码转换为 Python

在编程语言之间转换代码可能是一个具有挑战性的任务,尤其是当这些语言具有不同的范式和语法特性时。然而,C# 和 Python 的许多基本构造是相似的,因此在简单的情况下,转换过程归结为语法更改和某些概念的适应。

C# 库示例(MyLibrary.cs)

using System;

namespace MyLibrary
{
    public class Greeting
    {
        public string SayHello(string name)
        {
            return $"Hello, {name}!";
        }
    }
}

将库翻译成 Python(mylibrary.py)

class Greeting:
    def say_hello(self, name):
        return f"Hello, {name}!"

在 Python 项目中使用翻译后的库的示例

# 导入我们的类
from mylibrary import Greeting

# 创建 Greeting 类的实例
greet = Greeting()

# 使用 say_hello 方法
message = greet.say_hello("World")
print(message)

在这样一个简单的示例中,转换看起来非常吸引人,不是吗?但让我们看看这种方法的优缺点。

代码转换的优点

  • 自主性: 生成的 Python 代码不依赖于与 C# 交互的外部库或工具。这可以简化其在 Python 环境中的部署和使用。
  • 兼容性: 转换后的库接口可以使用 Python 生态系统中提供的任何数据类型,从而增强灵活性和开发的便利性。
  • 性能: 在某些情况下,转换后的代码可能比包装后的代码运行得更快,因为不需要额外的抽象层和跨语言接口调用。

代码转换的缺点

  • 劳动密集型: 代码转换需要大量的时间和劳动,特别是对于大型和复杂项目。需要仔细重写和测试所有代码。
  • 错误风险: 在重写代码时,有可能引入新的错误,这可能需要额外的时间进行调试。
  • 支持和同步: 如果原始 C# 库进行了更新,必须重新转换并在 Python 中测试代码。
  • 性能: Python 作为解释型语言,通常表现出低于编译型 C# 语言的性能。
  • 外部依赖: 转换使用外部库和依赖的 C# 代码可能具有挑战性。这些依赖需要被翻译成 Python(尽管其源代码并不总是可用),或者找到等效的库,这可能需要额外的努力和时间。

例如,转换以下代码为 Python 将非常具有挑战性:

using System;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace MyLibrary
{
    public class Greeting
    {
        public string SayHello(string name)
        {
            var tree = CSharpSyntaxTree.ParseText($"public class Hello {{ public string Name => \"{name}\"; }}");
            var root = (CompilationUnitSyntax)tree.GetRoot();

            var classDeclaration = (ClassDeclarationSyntax)root.Members[0];
            var className = classDeclaration.Identifier.Text;
            return $"Parsed class name: {className}";
        }
    }
}

劳动密集型、性能和外部依赖的问题通常会变得至关重要,这导致考虑另一种将 C# 库集成到 Python 中的方法——创建包装器。

为在 Python 中使用包装 C# 代码

包装 C# 代码涉及创建一个使用专门的库或工具将 C# 代码与 Python 连接的接口。这允许直接从 Python 代码调用用 C# 编写的方法。这种方法的优点是不需要重写现有代码,节省时间和精力——原始 C# 代码保持不变。此外,您可以利用 .NET 生态系统的所有功能,而不必担心将这些功能移植到 Python。

有几种方法可以包装 C# 代码,最流行的方法是使用 Python.NET 库和像我们的 CodePorting.Wrapper Cs2Python 这样的专用工具。

使用 Python.NET

上述的 C# 库 MyLibrary 可以如下在 Python 中使用:

import clr
clr.AddReference("MyLibrary.dll")
from MyLibrary import Greeting

greet = Greeting()

message = greet.SayHello("World")
print(message)

如果有对 Microsoft.CodeAnalysis 的依赖关系,情况会变得更复杂:

import clr
# 添加所有依赖项
clr.AddReference("Microsoft.CodeAnalysis.dll")
clr.AddReference("Microsoft.CodeAnalysis.CSharp.dll")
...
clr.AddReference("System.Collections.Immutable.dll")

clr.AddReference("MyLibrary.dll")
from MyLibrary import Greeting

greet = Greeting()

message = greet.SayHello("World")
print(message)

显式连接外部依赖项和其他限制的必要性,例如传递某些数据类型的困难,可能会使使用 Python.NET 库集成 C# 代码变得复杂。在这种情况下,值得考虑提供更方便和自动化解决方案的替代工具。

使用 CodePorting.Wrapper Cs2Python

CodePorting.Wrapper Cs2Python 提供了一种便捷的方法,通过创建一个 Wheel 包(WHL)形式的标准 Python 扩展,将 C# 库集成到 Python 中。这个包可以通过 pip 轻松安装,并用于 Python 项目。该工具会自动生成一个中间层,将 C# 代码与 Python 连接起来。此外,C# 库的所有依赖项都会自动包含在包中。

在这两种情况下,使用 CodePorting.Wrapper Cs2Python 包装的 MyLibrary 库将如下所示:

from mylibrary import Greeting

greet = Greeting()

message = greet.say_hello("World")
print(message)

如您所见,这完全复制了完整代码转换情况下的使用示例。但是,我们不需要将 Microsoft.CodeAnalysis 代码转换为 Python 或找到其等效的代码。

现在让我们考虑一下使用包装将 C# 代码集成到 Python 中的优缺点。

包装代码的优点

  • 集成的便利性: 包装允许在 Python 中轻松使用现有的 C# 代码,减少了重写代码所需的时间和精力。对于大型或复杂的库来说,这尤其有用。
  • 保持原始代码的性能和功能: 包装的 C# 代码可以比等效的 Python 代码更快地执行任务,尤其是在计算密集型应用中。此外,这还可以利用原始 C# 库提供的所有功能。
  • 简化维护和更新: 对 C# 库所做的任何更改都会通过包装自动在 Python 中可用,消除了同步 C# 和 Python 实现之间更改的需要。

使用 CodePorting.Wrapper Cs2Python 的优点

  • 过程自动化: CodePorting.Wrapper Cs2Python 会自动生成将 C# 代码与 Python 连接的中间层。这显著简化了集成过程,降低了出错的可能性。
  • 依赖管理: C# 库的所有依赖项都会自动包含在 Python 扩展模块中,消除了手动连接每个依赖项的需要,并简化了库对最终用户的部署。
  • 使用便利: 通过 pip 安装和使用生成的库 Wheel 包,使过程变得简单直观。这样,用户可以轻松地将库的功能集成到他们的项目中,而不需要深厚的技术知识。

包装代码的缺点

  • 需要额外的工具: 包装需要使用额外的库或工具。
  • 对数据类型的支持有限: 某些数据类型在 C# 和 Python 之间传输可能很困难,限制了使用某些库的能力。
  • 调试和诊断: 查找和修复错误可能更复杂,因为需要考虑两个不同运行时环境(Python 和 .NET)之间的交互。
  • 文档和支持: 某些包装工具的文档和支持可能有限,使得解决问题变得困难。

结论

将 C# 库集成到 Python 中可以使您在 Python 项目中有效地使用现有的 C# 代码。选择包装还是代码转换取决于项目的具体需求。包装允许您快速轻松地在 Python 中使用 C# 库,最小化时间和精力。代码转换需要更多资源,但可以提供更深入的集成。

选择正确的集成方法将帮助您最大限度地利用资源并实现您的目标。

相关新闻