
Python.NET自定义Codec详解2个接口实现Python与.NET双向无缝编组的完整指南【免费下载链接】pythonnetPython for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers.项目地址: https://gitcode.com/gh_mirrors/py/pythonnetPython.NET 是连接 Python 与 .NETCLR的开源互操作框架其Codec 系统通过IPyObjectEncoder和IPyObjectDecoder2个接口让开发者自定义类型转换marshalling/unmarshalling实现 Python 与 .NET 之间的双向无缝编组。本文将带你快速上手这套轻量而强大的扩展机制。什么是 Codec双向编组的两条通道在 Python 调用 C# 方法时参数需要在两种运行时之间转换。Python.NET 内置了数字、字符串、布尔等常见类型的自动转换而自定义类型转换 Codec就是用来处理内置转换覆盖不到的场景例如接口方向核心方法作用IPyObjectEncoder.NET → PythonCanEncode(Type)、TryEncode(object)把 CLR 对象编码为 Python 对象IPyObjectDecoderPython → .NETCanDecode(PyType, Type)、TryDecodeT(PyObject, out T)把 Python 对象解码为 CLR 类型两个接口都非常小每个只有 2 个方法定义见IPyObjectEncoder.csIPyObjectDecoder.cs设计要点接口采用Can*Try*的两段式协议——先用CanEncode/CanDecode判断我能不能处理这个类型再用TryEncode/TryDecode实际转换。这让运行时可以安全地遍历多个已注册 Codec而不必担心异常。3步定义并注册自定义 Codec第1步实现接口以把 CLR 的decimal转成 Python 的int、反向再转回来为例只需实现一个类同时满足两个接口官方文档 codecs.rst 中也有同样的示例接口定义。第2步注册到 PyObjectConversions注册入口是静态类 PyObjectConversions.csPyObjectConversions.RegisterEncoder(myEncoder); // .NET → Python PyObjectConversions.RegisterDecoder(myDecoder); // Python → .NET第3步验证注册后无需任何额外配置ToPython()扩展方法与AsT()等转换路径会自动查询已注册的 Codec。可参考 test_codec.py 中的测试写法用 fixture 在每个用例前后调用Reset()保证 Codec 注册状态干净可控。内置 Codec 示例4个现成的转换器Codecs目录下内置了多个可直接学习甚至直接使用的 Codec是理解接口用法的最佳范例EnumPyIntCodec.cs —— 枚举与 Python int 的双向转换已标记[Obsolete]现由内置机制接管ListDecoder.cs —— Pythonlist到IListT的惰性包装SequenceDecoder.cs —— Python 序列协议对象到ICollectionTIterableDecoder.cs —— 任意 Python 可迭代对象到IEnumerableTTupleCodecs.cs、RawProxyEncoder.cs以ListDecoder为例它的CanDecode同时校验源是 Python list 类型且目标是IList泛型TryDecode则返回一个惰性包装器 ListWrapper.cs读取时才真正遍历 Python 列表——这是高效实现 Codec 的常用思路。EncoderGroup 与 DecoderGroup控制多 Codec 优先级当注册了多个 Codec 时Python.NET优先尝试先注册的。如果你需要一组高优先级 Codec并允许事后动态增补应使用分组容器EncoderGroup.csDecoderGroup.csvar highPriority new EncoderGroup(); PyObjectConversions.RegisterEncoder(highPriority); // 组内整体优先 highPriority.Add(new SomeEncoder()); // 之后还能继续添加分组本身实现了IPyObjectEncoder/IPyObjectDecoder因此可以嵌套组合。其行为在 CodecGroups.cs 中有完整的单元测试覆盖例如验证同类型多个编码器时按注册顺序取第一个成功者。转换是如何被触发的理解 Converter.cs 调用链整个系统的调度中枢是 Converter.cs编码方向Converter.ToPython()先检查EncodableByUser枚举、DateTime、Decimal及普通对象命中后调用PyObjectConversions.TryEncode询问你的 Codec解码方向Converter.ToManagedValue()处理完包装对象与基元类型后同样把自定义 Codec 的机会交给PyObjectConversions.TryDecode。值得注意的是PyObjectConversions内部用ConcurrentDictionary按CLR 类型和Python 类型, 目标 CLR 类型二元组做了查找缓存首次匹配后直接复用委托因此注册一次、收益长期性能开销可忽略。从 Python 侧注册 Codec双向都能扩展Codec 注册并不局限于 C# 代码。在 Python 端同样可以拿到这些 APItest_codec.py 就演示了从 Python 侧注册IterableDecoder后把一个自定义可迭代类传给接受IEnumerableobject参数的 C# 方法import Python.Runtime Python.Runtime.Codecs.IterableDecoder.Register()这使得用 Python 脚本动态扩展 .NET 应用的类型转换成为可能是嵌入场景C# 宿主 Python 脚本里非常实用的技巧。常见问题 FAQ1. Codec 和内置转换是什么关系内置转换数字、字符串、数组等永远生效Codec 是针对用户类型的补充注册后会覆盖部分默认行为如 Python int 到枚举的转换。2. 一个类型能注册多个 Codec 吗可以。运行时会按注册顺序依次尝试第一个返回成功非null/true的生效用EncoderGroup/DecoderGroup可以更灵活地管理优先级。3. 如何彻底清除已注册的 Codec如测试中参考 CodecTest.cs 中CodecResetter的做法它会调用PyObjectConversions的内部重置逻辑并释放分组保证用例隔离。小结要点说明核心接口IPyObjectEncoder编码、IPyObjectDecoder解码各 2 个方法注册入口PyObjectConversions.RegisterEncoder / RegisterDecoder优先级管理EncoderGroup/DecoderGroup先注册者优先支持嵌套调度中枢Converter.ToPython/ToManagedValue自动询问已注册 Codec只需实现2 个接口、注册 1 次你的自定义类型就能在 Python 与 .NET 之间无缝流转。更多细节可查阅官方文档 codecs.rst 以及 src/runtime/Codecs 目录下的全部源码。【免费下载链接】pythonnetPython for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers.项目地址: https://gitcode.com/gh_mirrors/py/pythonnet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考