调用IronPython函数时CodeContext的相关性

本文关键字:相关性 CodeContext IronPython 函数 调用 | 更新日期: 2023-09-27 18:09:23

我正在从c#调用IronPython函数。似乎在定义上,这个函数捕获了它的原始作用域。当我稍后在没有显式作用域的情况下调用它时,它仍然可以访问原始作用域中的值。即使我更改了作用域值,它也能正确读取新值。看一下这个例子:

using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace IronPythonFuncTest {
    class Program {
        static void Main() {
            ScriptEngine scriptEngine = Python.CreateEngine();
            // Create scope with a global value for the script to use
            ScriptScope scriptScope = scriptEngine.CreateScope();
            scriptScope.SetVariable("someGlobalValue", 10);
            // Execute script defining function foo(x)
            string script = "def foo(): print(someGlobalValue)";
            ScriptSource scriptSource = scriptEngine.
                CreateScriptSourceFromString(script, SourceCodeKind.Statements);
            scriptSource.Execute(scriptScope);
            // Extract foo from the scope
            PythonFunction foo = scriptScope.GetVariable<PythonFunction>("foo");
            // Change someGlobalValue
            scriptScope.SetVariable("someGlobalValue", 42);
            // Call foo. This prints 42, not 10 (or nothing).
            PythonCalls.Call(foo);
        }
    }
}

现在我想知道:PythonCalls.Call()的大多数重载期望CodeContext对象(如果我理解正确的话,它主要代表一个作用域)。如果我像上面那样调用IronPython函数,而不传递代码上下文,我会失去一些东西吗?考虑到函数显然在创建时捕获了它的原始作用域,传递额外的代码上下文似乎没有任何意义。在某些情况下,我做不做会有区别吗?

调用IronPython函数时CodeContext的相关性

为什么叫foo而不是PythonCall.Call ?尝试这样做:scriptScope.Host.ScriptEngine.Operations.InvokeMember(CLASS-Instance, METHOD-Name, ARGUMENTS);比Ironpython将正确地处理CodeContext自己。你可以在这里找到一个示例实现:DlrClass/InvokeMember.

据我所知,CodeContext不仅仅是作用域,只要看看定义:

/// <summary>
/// Captures and flows the state of executing code from the generated 
/// Python code into the IronPython runtime.
/// </summary>    
[DebuggerTypeProxy(typeof(CodeContext.DebugProxy)), DebuggerDisplay("module: {ModuleName}", Type="module")]
public sealed class CodeContext { // ... }

希望这对你有帮助!