gpt4 book ai didi

c# - 使用 IronPython 的无限递归引用

转载 作者:太空宇宙 更新时间:2023-11-03 16:02:05 24 4
gpt4 key购买 nike

如果这是一个愚蠢的问题,请提前道歉。总的来说,我是 Python 的新手(对其他语言根本不是新手),尤其是 IronPython 的新手。

我正在尝试通过我的 C# 项目运行 Python 项目。我将所有相关的 Python 资源作为嵌入式资源包含在内(我将其读入 Dictionary<string,string>,其中键是模块的名称,值是文件的内容。

我已经实现了一个类,与对“Custom IronPython import resolution”的回复中建议的类非常相似,如下所示:

public class PythonInstance
{
private ScriptEngine engine;
private ScriptScope scope;
private ScriptSource source;
private CompiledCode compiled;
private object pythonClass;
private delegate object ImportDelegate(CodeContext context, string moduleName, PythonDictionary globals, PythonDictionary locals, PythonTuple tuple);
private Dictionary<string, string> importModulesCode = new Dictionary<string, string>();

public PythonInstance(string code, Dictionary<string,string> modulesCode, string className = "PyClass")
{
this.importModulesCode.Clear();
foreach(KeyValuePair<string,string> module in modulesCode)
this.importModulesCode.Add(module.Key, module.Value);

//creating engine and stuff
this.engine = Python.CreateEngine();
this.scope = Python.GetBuiltinModule(engine);//engine.CreateScope();

this.scope.SetVariable("__import__", new ImportDelegate(this.ImportModuleFromResources));

//loading and compiling code
this.source = this.engine.CreateScriptSourceFromString(code, SourceCodeKind.Statements);
this.compiled = this.source.Compile();

//now executing this code (the code should contain a class)
this.compiled.Execute(this.scope);

//now creating an object that could be used to access the stuff inside a python script
this.pythonClass = this.engine.Operations.Invoke(this.scope.GetVariable(className));
}

public void SetVariable(string variable, dynamic value)
{
this.scope.SetVariable(variable, value);
}

public dynamic GetVariable(string variable)
{
return this.scope.GetVariable(variable);
}

public void CallMethod(string method, params dynamic[] arguments)
{
this.engine.Operations.InvokeMember(this.pythonClass, method, arguments);
}

public dynamic CallFunction(string method, params dynamic[] arguments)
{
return this.engine.Operations.InvokeMember(this.pythonClass, method, arguments);
}

protected object ImportModuleFromResources(CodeContext context, string moduleName, PythonDictionary globals, PythonDictionary locals, PythonTuple tuple)
{
if ((this.importModulesCode.Keys.Contains(moduleName)) && (!string.IsNullOrWhiteSpace(this.importModulesCode[moduleName])))
{
string rawScript = this.importModulesCode[moduleName];
this.engine.Execute(rawScript, this.scope);
Scope ret = HostingHelpers.GetScope(this.scope);
this.scope.SetVariable(moduleName, ret);
return ret;
}
else
{ // fall back on the built-in method
return Builtin.__import__(context, moduleName);
}
}
}

现在这似乎工作正常。只是当我尝试运行 Python 代码时出现堆栈溢出异常,因为引用似乎是递归的。

我的主 pyw 文件包含以下标题:

import os, sys, getopt, __builtin__
from pyglossary.glossary import confPath, VERSION

第一个导入是 os我从 IronPython Lib 中取出的模块,所以我的 ImportModuleFromResources方法使用第一个 if block 和引用得到解析。

下一次迭代尝试导入 sys (使用 else block 和内置模块导入),然后是 errno (同样是 else block 和内置模块导入)-> nt (再次内置导入)-> nt (再次..) -> ntpath (是的..) -> 然后回到 os再次,并继续进行无限递归以再次遍历模块...(当然会导致堆栈溢出)。

因为我不是 Python 专家,而且我不知道 IronPython 的标准库模块以及它们如何相互引用,所以我确定我做错了一些非常基本的错误,但不确定我需要哪个引用删除、操作我包含的一个 Lib 文件(我认为不太可能),或改进我的 ImportModuleFromResources方法以避免递归引用..

帮助将不胜感激。谢谢!

最佳答案

我已经像Einar Egilsson一样做了已在 Custom IronPython import resolution 中提出=> 使用 PlatformAdaptationLayer

通过这种方式,ironpython 使用自己的机制来搜索模块,并且仅在找不到模块时才使用您的代码。

关于c# - 使用 IronPython 的无限递归引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20890935/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com