资讯详情

资讯详情

Python.NET继承进阶:用Python类继承C类并优雅重写虚方法

Python.NET继承进阶用Python类继承C#类并优雅重写虚方法【免费下载链接】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.NETPython for .NET是一个让 Python 与 .NET 公共语言运行时CLR几乎无缝集成的开源桥接库它既让 Python 程序员能直接调用 C# 类型和方法也让 .NET 开发者获得强大的应用脚本化工具。本文带你进阶它的继承机制——如何用 Python 类继承 C# 类、优雅重写虚方法virtual method、调用基类方法并正确处理构造函数与事件。为什么选择 Python.NET 做跨语言继承传统方案里Python 与 .NET 通信往往要写 COM 组件或 REST 接口成本高、类型不安全。Python.NET 的做法更原生C# 类型直接映射为 Python 类型System.String、System.Collections.Hashtable等都能被 Python 直接继承双向可用Python 子类既能被 Python 代码使用也能被 C# 代码实例化和调用零额外胶水代码无需手写代理类运行时自动生成所需的互操作类型。官方文档对此的描述是托管类也可以被 Python 子类化详见 doc/source/python.rst。一分钟上手 Python.NET 环境开始前先确认环境。Python.NET 可通过包管理器安装核心入口是clr模块源码见 clr.py 和 pythonnet/runtime/import clr # 加载 .NET 程序集DLL后即可 import 其中的命名空间 clr.AddReference(System.Windows.Forms) import System.Windows.Forms as WinForms一个经典的入门例子是 Windows Forms 子类化定义一个class HelloApp(WinForms.Form)重写点击事件处理器就得到了一个完整的 GUI 应用。完整代码在仓库演示目录demo/helloform.py。Python 类继承 C# 类三步走1️⃣ 直接继承托管类C# 类在 Python 眼里就是一个普通基类语法与继承 Python 类完全一致。比如继承 .NET 的Hashtablefrom System.Collections import Hashtable class MyTable(Hashtable): def how_many(self): return self.Count table MyTable() table[one] one # 直接调用 C# 方法 print(table.how_many()) # - 1table.Count、table.Add这些 C# 成员和 Python 定义的how_many()可以在同一个对象上自然共存。这个用例来自测试代码 tests/test_class.py。2️⃣ 继承 C# 接口实现契约如果 C# 侧定义了接口interfacePython 类同样可以直接实现它方法签名一一对应即可class InterfaceTestClass(IInterfaceTest): def foo(self): return InterfaceTestClass def bar(self, x, i): return /.join([x] * i)参考 tests/test_subclass.py。3️⃣ 了解一个关键限制⚠️Python 子类新增的成员对 C# 代码不可见。也就是说C# 能看到并调用的只有 C# 基类声明的接口虚方法、事件等你在 Python 里新写的方法只能由 Python 代码调用。设计时请让跨语言边界走 C# 已声明的虚方法。优雅重写 C# 虚方法Virtual Method这是本文的重点。Python.NET 对 C#virtual方法的支持非常完整Python 里定义的同名方法会自动成为重写override且对 C# 调用方生效。仓库内置了一套经典的测试基类SubClassTest源码src/testing/subclasstest.cs它声明了若干虚方法public virtual string foo() // 可被 Python 重写 public virtual string bar(string s, int i) public virtual string not_overriden() // 未重写也能正常工作Python 侧继承并重写class DerivedClass(SubClassTest): def foo(self): return DerivedClass # 重写虚方法 def super_foo(self): return super(DerivedClass, self).foo() # 优雅调用基类实现运行效果来自 tests/test_subclass.pyob.foo()返回DerivedClass—— 重写已生效ob.super_foo()返回foo—— 通过super()拿到了 C# 基类原始实现ob.not_overriden()返回not_overriden——没有重写的虚方法依然走 C# 默认实现不会报错。 小技巧如果不想依赖super()也可以显式调用基类方法SubClassTest.foo(self)两种写法在测试代码中都有覆盖tests/test_subclass.py。未重写也不慌对 C# 侧而言这是标准的多态虚方法调用会分派到你重写的 Python 版本没重写的则维持 C# 行为。这种按需重写、其余照旧的特性让 Python.NET 非常适合给现有 .NET 框架类打补丁式增强而不必修改 C# 源码。进阶技巧__namespace__与构造函数用__namespace__决定生成的 CLR 类型名Python 子类在底层会被 Python.NET 动态发射成一个真正的 CLR 类型实现细节见 src/runtime/Types/ClassDerived.cs。类属性__namespace__用于控制该类型的 CLR 命名空间这是让 C# 代码能反向引用你的 Python 子类的前提class DerivedClass(SubClassTest): __namespace__ Python.Test.MyApp ...⚠️__namespace__必须是合法的字符串赋错类型如 3会在实例化时抛出TypeError参见回归测试 tests/test_subclass.py。正确调用 C# 基类构造函数如果基类有带参构造函数Python 的__init__里需要显式调用class SubClass(ClassCtorTest2): def __init__(self, v): ClassCtorTest2.__init__(self, v) # 调用 C# 构造函数 self.value2 v示例来自 tests/test_class.py。让 C# 也能调用你的__init__clrmethod若希望C# 代码直接 new 出你的 Python 子类可用clr.clrmethod装饰器声明可被 CLR 调用的签名class TestX(System.Object): __namespace__ test_clr_subclass_init_from_clr clr.clrmethod(None, [int, str]) def __init__(self, i, s): ...C# 端即可通过Type.GetConstructors()/GetMethod(__init__)完成构造与初始化完整验证见 tests/test_subclass.py。C# 代码实例化 Python 子类反过来呢Python.NET 完全支持 C# 侧 new 出 Python 定义的类型。仓库的 C# 嵌入测试 src/embed_tests/Inheritance.cs 演示了这套玩法Python 子类Inherited重写了虚方法virt()返回-42C# 侧new Inherited()后调用virt()拿到的正是 Python 重写的值 ——跨语言多态双向成立isinstance检查也能正确穿过继承链含孙类。这正是优雅重写的完整闭环C# 定义虚方法契约 → Python 子类重写实现 → C# 调用方无感享受新逻辑。事件Event处理继承的另一半继承 C# 类还常涉及事件。C# 事件在 Python 中体现为add_X/remove_X方法对Python 子类可以完整实现一套事件机制参考 tests/test_subclass.py 的DerivedEventTestdef add_TestEvent(self, handler): self.event_handlers.append(handler) def remove_TestEvent(self, handler): self.event_handlers.remove(handler) def OnTestEvent(self, value): for handler in self.event_handlers: handler(self, EventArgsTest(value))也可以更 Pythonic 地用语法x.TestEvent event_handler.handlertests/test_subclass.py。常见问题与避坑指南问题说明参考Python 新方法 C# 看不到属设计预期跨语言边界走 C# 虚方法doc/source/python.rst忘记__namespace__C# 无法按类型定位 Python 子类tests/test_subclass.py基类带参构造__init__中需显式调用Base.__init__(self, ...)tests/test_class.py循环引用对象回收Python 子类实例可被 GC 正常回收含循环引用场景tests/test_subclass.py 此外从 Python 子类内部抛出的异常C# 侧能拿到完整的 Python traceback排错体验友好验证代码见 tests/test_subclass.py。相关代码与文档速查继承与虚方法测试Python 侧tests/test_subclass.py、tests/test_class.py继承测试夹具C# 基类定义src/testing/subclasstest.csC# 嵌入 Python 子类的端到端测试src/embed_tests/Inheritance.cs动态类型生成核心实现src/runtime/Types/ClassDerived.csGUI 子类化实战示例demo/helloform.py官方文档中Python 使用 CLR章节doc/source/python.rst写在最后Python.NET 的继承机制把 Python 的灵活与 .NET 的类型体系缝合成一体继承 C# 类只需三行代码重写虚方法只需一个同名函数super()让基类调用优雅如初。无论你是想给 C# 遗留框架加 Python 钩子还是用 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/pythonnet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →