如何在 C# 中重定向 IronPython 的标准输出?

Posted

技术标签:

【中文标题】如何在 C# 中重定向 IronPython 的标准输出?【英文标题】:How can I redirect the stdout of IronPython in C#? 【发布时间】: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

我做错了什么?

【问题讨论】:

【参考方案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));

【讨论】:

以上是关于如何在 C# 中重定向 IronPython 的标准输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何在NGINX中重定向一个网址

如何在 React 中重定向

如何在控制器操作中重定向到 aspx 页面

如何在PHP中重定向到同一页面

如何确定 URL 是不是在 PHP 中重定向?

如何在 laravel jetstream 中重定向?