我有以下C#类型:
[PythonType]
public class ScriptBase
{
public virtual int TestMe()
{
return 11;
}
}
然后,我尝试在python中创建一个继承自ScriptBase
的类:
from Base import ScriptBase
class TestClass (ScriptBase):
pass
尝试执行此脚本将生成:TypeErrorException: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
下面是我创建引擎和注册类型的过程:
// Executed to test
ScriptEngine _engine = Python.CreateEngine();
// Create base module
ScriptScope _gameScope = _engine.CreateModule("Base");
// Expose ScriptBase class in the module
_gameScope.SetVariable(nameof(ScriptBase), typeof(ScriptBase));
// Load the source from a file stream through a wrapper and compile
ScriptSource source = engine.CreateScriptSource(new CodeProvider(inStream), package, Encoding.ASCII, SourceCodeKind.Statements);
CompiledCode compiled = source.Compile();
// Create new module for the inheriting classes
_scope = engine.CreateModule(package);
// Execute the code -- this line throws an exception
compiled.Execute(_scope);
我试过导入CLR并定义__init__
和__new__
,但没有什么变化。.CreateModule
方法适用于示例化和管理现有类型,只是继承部分似乎被破坏了--我遗漏了什么步骤吗?
我不是很精通python,所以我不知道这条消息抱怨什么,我已经尝试了很多在线方法,但似乎总是在同一个地方结束。
运行时是mono,目标是.Net 4.x。下面是完整的调用堆栈。
TypeErrorException: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
IronPython.Runtime.Types.PythonType.FindMetaClass (IronPython.Runtime.Types.PythonType cls, IronPython.Runtime.PythonTuple bases) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Runtime.Operations.PythonOps.MakeClass (IronPython.Runtime.FunctionCode funcCode, System.Func`2[T,TResult] body, IronPython.Runtime.CodeContext parentContext, System.String name, IronPython.Runtime.PythonTuple bases, IronPython.Runtime.PythonDictionary keywords, System.String selfNames) (at <57a5bd653356491bba8a61ecf9211193>:0)
Microsoft.Scripting.Interpreter.FuncCallInstruction`8[T0,T1,T2,T3,T4,T5,T6,TRet].Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) (at <9784853821ea47dbb6bb1f3e03091049>:0)
Microsoft.Scripting.Interpreter.Interpreter.Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) (at <9784853821ea47dbb6bb1f3e03091049>:0)
Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet] (T0 arg0, T1 arg1) (at <9784853821ea47dbb6bb1f3e03091049>:0)
IronPython.Compiler.PythonScriptCode.RunWorker (IronPython.Runtime.CodeContext ctx) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Compiler.PythonScriptCode.Run (Microsoft.Scripting.Runtime.Scope scope) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Compiler.RuntimeScriptCode.InvokeTarget (Microsoft.Scripting.Runtime.Scope scope) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Compiler.RuntimeScriptCode.Run (Microsoft.Scripting.Runtime.Scope scope) (at <57a5bd653356491bba8a61ecf9211193>:0)
Microsoft.Scripting.Hosting.CompiledCode.Execute (Microsoft.Scripting.Hosting.ScriptScope scope) (at <0d164baeace648b2930cfd25249cf9f3>:0)
(wrapper remoting-invoke-with-check) Microsoft.Scripting.Hosting.CompiledCode.Execute(Microsoft.Scripting.Hosting.ScriptScope)
1条答案
按热度按时间wkyowqbh1#
在浏览了IronPython源代码之后,我已经设法自己找到了解决方案(感谢开源软件的好人,感谢你们的工作)。
事实证明,正确地将.net
Type
暴露给IronPython世界是通过DynamicHelpers.GetPythonTypeFromType(System.Type)
的,我目前正在使用这个扩展方法在ScriptScope
中注册我的类型:希望这能帮到什么人。