Неважно, я просмотрел исходный код IronPython 2.0.3 и придумал следующее:
- a
PythonContext
является Microsoft.Scripting.Runtime.LanguageContext
- языковой контекст
ScriptEngine
можно получить с помощью метода Microsoft.Scripting.Hosting.Providers.HostingHelpers.GetLanguageContext(ScriptEngine)
- если у вас есть
ScriptEngine
для python, тогда вы можете просто разыграть.
Ничего себе. Так что теперь у меня наконец есть мой PythonContext
! Поэтому я позвоню CreateModule
и PublishModule
и буду дома перед чаем!
Подождите. Во-первых, второй аргумент CreateModule
- это Microsoft.Scripting.Runtime.Scope
. Все, что у нас есть, это Microsoft.Scripting.Hosting.ScriptScope
. Который содержит Scope
, за исключением того, что его метод доступа равен internal
Поэтому сначала нам нужно подумать.
Вот мой пример кода, дополненный предложенным мной решением:
/// <summary>
/// Set up an IronPython environment - for interactive shell or for canned scripts
/// </summary>
public void SetupEnvironment(ScriptEngine engine, ScriptScope scriptScope)
{
// add variables from Revit
scriptScope.SetVariable("__revit__", _commandData.Application);
scriptScope.SetVariable("__commandData__", _commandData);
scriptScope.SetVariable("__message__", _message);
scriptScope.SetVariable("__elements__", _elements);
scriptScope.SetVariable("__result__", (int)Result.Succeeded);
// add preconfigures variables
scriptScope.SetVariable("__vars__", RevitPythonShellApplication.GetVariables());
// add the current scope as module '__main__'
var languageContext = Microsoft.Scripting.Hosting.Providers.HostingHelpers.GetLanguageContext(engine);
var pythonContext = (IronPython.Runtime.PythonContext)languageContext;
var module = pythonContext.CreateModule(null, GetScope(scriptScope), null, IronPython.Runtime.ModuleOptions.None);
pythonContext.PublishModule("__main__", module);
// add the search paths
AddSearchPaths(engine);
}
/// <summary>
/// Be nasty and reach into the ScriptScope to get at its private '_scope' member,
/// since the accessor 'ScriptScope.Scope' was defined 'internal'.
/// </summary>
private Microsoft.Scripting.Runtime.Scope GetScope(ScriptScope scriptScope)
{
var field = scriptScope.GetType().GetField(
"_scope",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
return (Microsoft.Scripting.Runtime.Scope) field.GetValue(scriptScope);
}
Я специально сохранил все пространства имен в типах. Я нахожу код IronPython довольно сложным для понимания и часто путаюсь с тем, что и где определено.