zoukankan      html  css  js  c++  java
  • 一起谈.NET技术,在.NET中嵌入IronPython 交互 狼人:

      随着IronPyhon 2.0 的发布,.NET Dynamic Language Runtime 也更加成熟了,在2.0中我们可以用动态脚本以粘合剂的方式编写架构体系中的各种逻辑单元,既便于修改,又能灵活适合多变的业务场景。当然,我的目标是在 Platform Framework 中能嵌入脚本引擎,而不是用 ipy.exe 去执行一个“独立”的任务。要让.net 项目能真正跟脚本进行交互,还得需要提供脚本引擎的实现。这得提到DLR一些基本概念了。

      下图摘自 DLR 帮助文件,通过它我们基本可以了解基于 DLR 的组成方式。

     

          下图描述了 DLR 的基本执行流程。

     

      ScriptRuntime:创建 DLR 运行环境,这是整个执行过程的起始点,它表示一个全局的执行状态(比如程序集引用等等)。每个应用程序域(AppDomain)中可以启动多个 ScriptRuntime。

      ScriptScope:构建一个执行上下文,其中保存了环境及全局变量。宿主(Host)可以通过创建不同的 ScriptScope 来提供多个数据隔离的执行上下文。

      ScriptEngine: DLR 动态语言(比如 IronPython)执行类,可于解析和执行动态语言代码。

      ScriptSource:操控动态语言代码的类型,我们可以编译(Compile)、读取(Read Code Lines)或运行(Execute)代码。

      CompiledCode:调用 ScriptSource.Compile()将源代码编译成 CompiledCode,这样多次执行就无需重复编译,从而提高执行性能。

      ObjectOperations:提供了相关方法,允许我们在宿主(Host)中操作 DLR 对象成员(Member)。

      现在我们来构建脚本引擎

      当然我们必须加入IronPyhton提供的相关引用并导入命名空间

      using IronPython.Hosting;

      using IronPython.Compiler;

      using IronPython.Runtime;

      using Microsoft.Scripting;

      using System.Runtime.Remoting;

      1、Hello World

      以下为引用的内容:

    var py = @"def test():
      return ‘hello world~!’;
      print test();
    "var engine = Python.CreateEngine();
      var code
    = engine.CreateScriptSourceFromString(py, SourceCodeKind.Statements);
      code.Execute();

      输出: hello world~!

      注意:Python 对于源代码缩进的格式有严格要求。

      2、给Python上下文提供变量

    var scope = engine.Runtime.Globals; //engine.Runtime.CreateScope();
      scope.SetVariable(“x”, 123);

      3、读取Python上下文中的变量

    var x = scope.GetVariable(“x”);

      可以看出 ScriptScope 可以在 Host 和 ScriptRuntime 间传递数据。

      4、对象实例共享

      以下为引用的内容:

    var py = @"o.X = o.X + 2;
      print o.X;
    "var engine = Python.CreateEngine();
      var code
    = engine.CreateScriptSourceFromString(py, SourceCodeKind.Statements);
      var scope
    = engine.Runtime.Globals;
      var o
    = new Data { X = 123 };
      scope.SetVariable(
    "o", o);
      code.Execute(scope);
      Console.WriteLine(o.X);

      载入程序集并由ScriptRuntime管理

      5、创建程序集test.dll

      以下为引用的内容:

    namespace My.Library
      {
      
    public class MyClass
      {
      
    public int Test(int x)
      {
      
    return ++x;
      }
      }
      }

      创建Host程序

      以下为引用的内容:

    var py = @"import clr;
      from My.Library import MyClass;
      from System import Console;
      o = MyClass();
      x.X = o.Test(x.X);
      Console.WriteLine(x.X);
    "var engine = Python.CreateEngine();
      engine.Runtime.LoadAssembly(Assembly.GetAssembly(
    typeof(int))); // mscorlib.dll
      engine.Runtime.LoadAssembly(Assembly.LoadFrom("test.dll")); // test.dll
      var code = engine.CreateScriptSourceFromString(py, SourceCodeKind.Statements);
      var scope
    = engine.Runtime.Globals;
      var x
    = new Data { X = 123 };
      scope.SetVariable(
    "x",x);
      code.Execute(scope);
      Console.WriteLine(x.X);

      读取Python上下文对象实例属性

      以下为引用的内容:

    var py = @"class Class1:
      def __init__(self):
      self.i = 100
      def inc(self):
      self.i=self.i+100
      o = Class1()
    "var o = scope.GetVariable("o");
      var i
    = engine.Operations.GetMember(o,"i");

      读取Python上下文对象实例方法

    engine.Execute("o.inc()", scope); //已经在上下文环境中执行此对象方法
  • 相关阅读:
    ThinkPHP第八天(U函数放置在外部JS不会被解析,错误界面定制,错误信息变量)
    ThinkPHP第七天(F函数使用,项目分组配置,项目分组模板文件放置规则配置)
    thinkphp第二天
    ThinkPHP第五天(提交类型判定常量IS_POST等,错误页面种类,Model实例化方式,模板中使用函数,foreach循环,模板中.语法配置)
    高阶函数、函数嵌套和闭包
    递 归
    函数式编程
    命名空间
    函数的参数
    循环语句
  • 原文地址:https://www.cnblogs.com/waw/p/2158604.html
Copyright © 2011-2022 走看看