【问题标题】:How can I redirect the stdout of IronPython in C#?如何在 C# 中重定向 IronPython 的标准输出?
【发布时间】:2011-03-04 13:21:58
【问题描述】:

我有以下几点:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button3_Click(object sender, EventArgs e)
    {
        try
        {
            var strExpression = @"
            import sys
            sys.stdout=my.write
            print 'ABC'
            ";
            var engine = Python.CreateEngine();
            var scope = engine.CreateScope();
            var sourceCode = engine.CreateScriptSourceFromString(strExpression);
            scope.SetVariable("my", this);
            var actual = sourceCode.Execute<string>(scope);
            textBox1.Text += actual;
        }
        catch (System.Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

    public void write(string s)
    {
        textBox1.Text += s;
    }
}

但我收到了一个Exception,它说没有write

我做错了什么?

【问题讨论】:

    标签: c# redirect ironpython stdout


    【解决方案1】:

    您可以直接从 c# 中设置流和文本编写器:

    engine.Runtime.IO.SetOutput(stream, txtWriter);
    engine.Runtime.IO.SetErrorOutput(stream, txtWriter);
    

    例如,要重定向输出,您可以覆盖 TextWriter 类,在您的文本框上写一个新的。


    例如

    在我的应用程序中,我重写了 StreamWriter 类,当在流上写入某些内容时会引发事件(这里只是代码的一部分):

    public class MyEvtArgs<T> : EventArgs
    {
        public T Value
        {
            get;
            private set;
        }
        public MyEvtArgs(T value)
        {
            this.Value = value;
        }
    }
    
    
    public class EventRaisingStreamWriter : StreamWriter
    {
        #region Event
        public event EventHandler<MyEvtArgs<string>> StringWritten;
        #endregion
    
        #region CTOR
        public EventRaisingStreamWriter(Stream s):base(s)
        { }
        #endregion
    
        #region Private Methods
        private void LaunchEvent(string txtWritten)
        {
            if (StringWritten != null)
            {
                StringWritten(this, new MyEvtArgs<string>(txtWritten));
            }
        }
        #endregion
    
    
        #region Overrides
    
        public override void Write(string value)
        {
            base.Write(value);
            LaunchEvent(value);
        }
        public override void Write(bool value)
        {
            base.Write(value);
            LaunchEvent(value.ToString());
        }
        // here override all writing methods...
    
        #endregion
    }
    

    然后在您的应用程序中,您应该执行以下操作:

        MemoryStream ms = new MemoryStream();
    
        EventRaisingStreamWriter outputWr = new EventRaisingStreamWriter(ms);
        outputWr.StringWritten += new EventHandler<MyEvtArgs<string>>(sWr_StringWritten);
    
        var engine = Python.CreateEngine();
        engine.Runtime.IO.SetOutput(ms, outputWr);
        engine.CreateScriptSourceFromString("print 'hello world!'").Execute();
    
    
        void sWr_StringWritten(object sender, MyEvtArgs<string> e)
        {
            textBox1.Text += e.Value;
        }
    

    【讨论】:

    • 非常酷的东西!但在您的最后一个代码 sn-p 中,它可能应该是 engine.Runtime.IO.SetOutput(...)
    【解决方案2】:

    您的示例即将生效。

    您看到的问题是因为sys.stdout=my.write 应该是sys.stdout=my。 Python 似乎也希望找到一个布尔值 softspace 属性。

    我在下面的代码中进行了这两项更改。希望现在应该可以按您的预期工作。

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                var strExpression = @"
    import sys
    sys.stdout=my
    print 'ABC' ";
    
                var engine = Python.CreateEngine();
                var scope = engine.CreateScope();
                var sourceCode = engine.CreateScriptSourceFromString(strExpression);
                scope.SetVariable("my", this);
                var actual = sourceCode.Execute(scope);
                textBox1.Text += actual;
            } catch (System.Exception ex) {
                MessageBox.Show(ex.ToString());
            }
        }
    
        public bool softspace;
    
        public void write(string s)
        {
            textBox1.Text += s;
        }
    }
    

    【讨论】:

      【解决方案3】:

      这对我来说很好用

              pyRuntime = Python.CreateRuntime();
              pyRuntime.IO.SetOutput(Console.OpenStandardOutput(), new UTF8Encoding(true, false));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多