【问题标题】:Embedding Python in C# via resources通过资源在 C# 中嵌入 Python
【发布时间】:2015-02-24 03:19:17
【问题描述】:

我一直在研究一个似乎无法解决的问题,所以我需要一些帮助!问题是我正在用 C# 编写一个程序,但我需要一个来自我创建的 Python 文件的函数。这本身没问题:

...Usual Stuff

using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting; 

namespace Program
{
    public partial class Form1 : Form
    {
        Microsoft.Scripting.Hosting.ScriptEngine py;
        Microsoft.Scripting.Hosting.ScriptScope s;
        public Form1()
        {
            InitializeComponent();

            py = Python.CreateEngine(); // allow us to run ironpython programs
            s = py.CreateScope(); // you need this to get the variables

        }

        private void doPython()
        {
            //Step 1: 
            //Creating a new script runtime             
            var ironPythonRuntime = Python.CreateRuntime();

            //Step 2:
            //Load the Iron Python file/script into the memory
            //Should be resolve at runtime
             dynamic loadIPython = ironPythonRuntime.;

             //Step 3:
             //Invoke the method and print the result
             double n = loadIPython.add(100, 200);
             numericUpDown1.Value = (decimal)n;
         }
    }
}

但是,这要求文件“first.py”位于程序编译后的任何位置。因此,如果我想分享我的程序,我将不得不同时发送可执行文件和 python 文件,这非常不方便。我认为解决此问题的一种方法是将“first.py”文件添加到资源中并从那里运行......但我不知道如何做到这一点,或者即使可能。

当然,上面的代码不适用于此,因为 .UseFile 方法采用字符串参数而不是 byte[]。有谁知道我会如何进步?

【问题讨论】:

  • 人们不得不问为什么不能在 C# 中编写一个等效的函数。可以这么说,翻译 Python。
  • 你试图在python中调用的函数是什么,它有什么特别之处,又大又复杂?
  • stackoverflow.com/questions/15470090/… 拥有您需要的所有信息...(如果您不反对阅读原始文档/支持文章 - - support.microsoft.com/kb/319292
  • 我尝试过这样做,但我没有编写 python 代码(这很粗糙且未注释),并且在过去几天尝试用 c# 重写并没有成功。尽管我相信我理解 python 代码的作用并且我理解 python 语法足以翻译它,但我得到了相似但不同的结果。不仅如此,c# 版本的计算时间也慢得多。我还认为这是一个有趣的技术练习。

标签: c# python resources embed call


【解决方案1】:

让我们从可能可行的最简单的事情开始,您的代码看起来有点像以下:

// ...
py = Python.CreateEngine(); // allow us to run ironpython programs
s = py.CreateScope(); // you need this to get the variables
var ironPythonRuntime = Python.CreateRuntime();
var x = py.CreateScriptSourceFromFile("SomeCode.py");
x.Execute(s);
var myFoo = s.GetVariable("myFoo");
var n = (double)myFoo.add(100, 200);
// ...

我们想将var x = py.CreateScriptSourceFromFile(... 行替换为其他内容;如果我们可以将嵌入资源作为字符串获取,我们可以使用ScriptingEngine.CreateScriptSourceFromString()

Cribbing this fine answer,我们可以得到一些看起来有点像这样的东西:

string pySrc;

var resourceName = "ConsoleApplication1.SomeCode.py";
using (var stream = System.Reflection.Assembly.GetExecutingAssembly()
                          .GetManifestResourceStream(resourceName))
using (var reader = new System.IO.StreamReader(stream))
{
    pySrc = reader.ReadToEnd();
}
var x = py.CreateScriptSourceFromString(pySrc);

【讨论】:

  • 感谢您的回复,遗憾的是我无法让您的代码为我工作,我将“SomeCode.py”替换为“first.py”,将“myFoo”替换为“add”我想调用的“first.py”中的函数名。代码不会抛出错误,只会返回“null”,我不知道为什么。我错过了什么吗?
  • 您是否在程序集中嵌入了 python 文件?您对该嵌入式资源有正确的名称吗?这并不像您想象的那么容易猜到。
  • 我知道并感谢您抽出宝贵时间。我发现它不喜欢读取fileName.py,但是自己读取fileName没有问题。这样做意味着您的第一组指令运行良好。
猜你喜欢
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 2017-02-06
相关资源
最近更新 更多