首页 > 编程语言 >IronPython for C#(五)

IronPython for C#(五)

时间:2022-08-24 15:11:41浏览次数:54  
标签:Engine string C# System using IronPython public

通常情况下,是将C#代码共享到python脚本中,可以通过脚本调用C#的各个对象。

 

一、IronPythonRunner

创建IronPython运行器,可通过该运行器运行python脚本。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using IronPython.Compiler;
using IronPython.Hosting;
using IronPython.Runtime;

using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Hosting.Providers;
using Microsoft.Scripting.Runtime;

namespace IronPythonTest
{
    internal class IronPythonRunner
    {
        public ScriptEngine Engine { get; set; }
        ScriptScope _scope;

        public IronPythonRunner()
        {
            Dictionary<string, object> options = new Dictionary<string, object>();
            options["LightweightScopes"] = true;
            Engine = Python.CreateEngine(options);
            List<string> collectionStr = new List<string>();
            collectionStr.Add(AppDomain.CurrentDomain.BaseDirectory);

            //导入python库,若在脚本中不使用python库,可以不导入
            string[] libPaths = new string[]
            {
               Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"IronPythonLib"),  //
               @"C:/Program Files (x86)/IronPython 2.7/Lib",               // IronPython installed on PC (32 bit)
               @"C:/Program Files/IronPython 2.7/Lib",                      // IronPython installed on PC (64 bit)
            };

            for (int i = 0; i < libPaths.Length; i++)
            {
                DirectoryInfo di = new DirectoryInfo(libPaths[i]);
                if (di.Exists)
                {
                    collectionStr.Add(libPaths[i]);
                    break;
                }
            }
            Engine.SetSearchPaths(collectionStr);
            _scope = Engine.CreateScope();
        }

        private void AddSearchPaths(string fullFilePath)
        {
            ICollection<string> paths = Engine.GetSearchPaths();
            if (!paths.Contains(fullFilePath))
            {
                string direPath = Path.GetDirectoryName(fullFilePath);
                if (!string.IsNullOrWhiteSpace(direPath))
                {
                    paths.Add(direPath);
                    Engine.SetSearchPaths(paths);
                    DirectoryInfo directory = new DirectoryInfo(direPath);
                    foreach (var path in directory.GetDirectories())
                    {
                        AddSearchPaths(path.FullName);
                    }
                }
            }
        }

        public dynamic RunScriptByPath(string fullFilePath)
        {
            AddSearchPaths(fullFilePath);
            ScriptSource source = Engine.CreateScriptSourceFromFile(fullFilePath);
            return RunScript(source);
        }

        public dynamic RunScriptByString(string pythonCodeStr)
        {
            ScriptSource source = Engine.CreateScriptSourceFromString(pythonCodeStr);
            return RunScript(source);
        }

        private dynamic RunScript(ScriptSource source)
        {
            PythonCompilerOptions pco = (PythonCompilerOptions)Engine.GetCompilerOptions(_scope);
            pco.ModuleName = "__main__";
            pco.Module |= ModuleOptions.Initialize;
            CompiledCode code = source.Compile(pco);
            return code.Execute(_scope);
        }

        public void ShareVariableToScript(string name, object value)
        {
            IEnumerable<string> variables = _scope.GetVariableNames();
            if (!variables.Contains(name))
            {
                _scope.SetVariable(name, value);
            }
        }

        public Scope CustomImportModule(string moduleName, string scriptPath)
        {
            string rawScript = File.ReadAllText(scriptPath);
            ScriptScope scopetemp = Engine.CreateScope();
            var varNames = scopetemp.GetVariableNames();
            foreach (var kv in _scope.GetItems())
            {
                if (!varNames.Contains(kv.Key) && kv.Value != null)
                {
                    scopetemp.SetVariable(kv.Key, kv.Value);
                }
            }
            Engine.Execute(rawScript, scopetemp);
            Scope ret = HostingHelpers.GetScope(scopetemp);
            _scope.SetVariable(moduleName, ret);
            return ret;
        }

    }
}

 二、PythonModel

创建要传入python脚本的类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IronPythonTest
{
    public class PythonModel
    {
        public event Action<string> SendMessageEvent;
        public event Func<List<int>, int?> AddEvent;

        public string Name { get; set; }

        public int? Add(int a, int b)
        {
            return AddEvent?.Invoke(new List<int> { a, b });
        }

        public void GetValue(ref float arg1, out float? arg2, out List<int> arg3)
        {
            arg1 = 3.4f;
            arg2 = null;
            arg3 = new List<int> { 1, 3 };
            SendMessageEvent?.Invoke($"GetValue:arg1 = {arg1},arg2 = {arg2},arg3 = {string.Join(",", arg3)}");
        }

        public void SetValue(int[] arg1)
        {
            SendMessageEvent?.Invoke($"SetValue:{string.Join(",", arg1)}");
        }
    }
}

三、Program

创建控制台程序,实例化IronPythonRunner,并将PythonModel对象传入脚本中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IronPythonTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            PythonModel pythonModel = new PythonModel();
            IronPythonRunner runner = new IronPythonRunner();
            runner.ShareVariableToScript("VM", pythonModel);
            runner.ShareVariableToScript("WL", new Action<string>((str) =>
            {
                Console.WriteLine(str);
            }));
            runner.RunScriptByPath("test.py");
            Console.ReadKey();
        }
    }
}

四、test.py

创建test.py脚本

# !/usr/bin/python
# -*- coding: UTF-8 -*-

import System
import clr

from System import Array
from System.Collections.Generic import List

#获取代码传送到脚本的变量
vm = globals().get('VM')
wl = globals().get('WL')

#当然也可以直接使用
WL('Start')

def writeline(str):
    wl(str)

def add(lista):
    res = 0
    for a in lista:
        res += a
    wl('res = ' + str(res))
    return res

#订阅事件
vm.SendMessageEvent += writeline   
vm.AddEvent += add;

vm.SetValue(Array[int]([3,2,1]))   #定义一个整型数组

vm.Add(2,3)

#对应ref或out参数,需用clr.StrongBox定义
arg1 = clr.StrongBox[System.Single]()                    #定义强类型float
arg2 = clr.StrongBox[System.Nullable[System.Single]]()   #定义强类型float?
arg3 = clr.StrongBox[List[System.Int32]]()               #定义强类型List<int>
vm.GetValue(arg1, arg2, arg3)

 

标签:Engine,string,C#,System,using,IronPython,public
From: https://www.cnblogs.com/bridgew/p/16620018.html

相关文章

  • C#下载csv代码总结(解决中文乱码问题)
    ///<summary>///下载///</summary>///<paramname="startTime"></param>///<paramname="endTime"></param>publicvoidDownload(DateTime?startTime,D......
  • C# 读取MotherBoard的信息
    通过C#来读取PC的MotherBoard上的信息,如产品名称,制造商,版本等,方法如下:Reference中添加System.Management,并在头文件中引入该Assemble添加对应的类,并进行使用,如......
  • SpringMVC、MVC、JavaBean、表述层、三层架构
    来源:BV1Ry4y1574R?p=3、BV1Ry4y1574R?p=4SpringMVC是Spring的MVC模块,也就是来实现Web功能的模块。Spring里面包含有很多的模块,比如说SpringFramework是它的......
  • ASP.NET Core Docker容器部署
    最简单的部署操作方式1.安装辅助工具1.1安装Gitsudoyum-yinstallgit安装完成后输入git命令查看1.2安装Nginx(这种部署方式暂时没用到)参考文档:https://......
  • 历时2月,动态线程池 DynamicTp 发布里程碑版本 V1.0.8
    关于DynamicTpDynamicTp是一个基于配置中心实现的轻量级动态线程池管理工具,主要功能可以总结为动态调参、通知报警、运行监控、三方包线程池管理等几大类。经过多个版......
  • kafka的producer配置参数
    主要介绍下kafka的producer配置参数,只取了其中的一部分常用的,后续的有时间,也会补充一些,更多的详细参数,可以参考《kafka官网》,参数的内容,主要是选取《apachekafka实战》书......
  • CentOS安装部署Weblogic12.1.3
    开始以为和旧版安装一样,使用控制台的方式,下载bin文件,然后一步步在console执行下来就行了。万万没想到,从12C版本后,bin文件不提供了,改成全系统通用的jar文件(generic.jar)。......
  • 万物皆可集成系列:低代码对接泛微e-cology
    近些年来,当谈论到企业信息化的时候,OA作为集团化全员应用,在企业经营管理中使用非常广泛。众所周知,泛微e-cology作为面向大中型企业的平台型协同办公自动化系统,它的标准化功......
  • JS doc 接口文档生成器
    前言项目中使用到需要把js方法生成接口文档,使用到了JSdoc这个工具,使用该工具生成文档,需要在方法里加入注释,根据注释说明生成文档,这里顺便记录一下使用过程,模拟了一些j......
  • 用 Wireshark 分析 TCP 吞吐瓶颈
    https://www.kawabangga.com/posts/4794Debug网络质量的时候,我们一般会关注两个因素:延迟和吞吐量(带宽)。延迟比较好验证,Ping一下或者 mtr 一下就能看出来。这篇文章分......