使用 IronPython 覆盖 DLL 函数

Use IronPython to override DLL function

我想使用 IronPython 覆盖 dll 中的一个方法,以便以后对该方法的所有调用都转到 python 实现。我希望它基于已接受的答案 here.

中的技术

所以我尝试用以下内容制作一个 dll class:

namespace ClassLibrary1
{
    public class Class1
    {
        public static string test()
        {
            return "test";
        }
    }
}

然后我在 IronPython 中做了以下操作:

import clr
clr.AddReference("ClassLibrary1")

import ClassLibrary1

def _override():
    return "george"

ClassLibrary1.Class1.test = _override;

print ClassLibrary1.Class1.test();

然而,当运行 python 代码时,我得到以下异常:

An exception of type 'System.MissingMemberException' occurred in Snippets.debug.scripting but was not handled in user code

Additional information: attribute 'test' of 'Class1' object is read-only

有什么方法可以实现我想要的吗?

您正在尝试的是 monkey patch。它实际上不是覆盖,而是在运行时动态替换属性。

Monkey 补丁特定于 python,因此不能保证非 python classes.

相反,考虑从您的 C# class 派生一个新的 python class,并覆盖那里的方法。

只是为了扩展 Roland 的回答,考虑编写一个包装 python 模块。我从未使用过 IronPython,但我相信如果出现问题,您可以修复解决方案。

# class_library_1_wrapper.py
import clr
clr.AddReference("ClassLibrary1")
import ClassLibrary1 


class Class1:
    def __init__(self):
        self._clr_object = ClassLibrary1.Class1()

    def some_method():
        return self._clr_object.SomeMethod()

    @staticmethod
    def test():
        return "george"

此方法由 Cython 开发人员建议when importing C++ classes。另一个好处是你削弱了对 "ClassLibrary1" 的依赖,并且可以在不让其他模块知道的情况下回退到 Class1 的纯 IronPython 实现:

# class_library_1_wrapper.py
import clr
clr.AddReference("ClassLibrary1")

try:
    import ClassLibrary1
except ImportError:
    print 'sorry, no speed-ups'
    # Class1 IronPython implementation here
else:
    # Implement Class1 as described in the first snippet.

可以在 Werkzeug Python 库中找到这种方法。