如何在 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 的标准输出?的主要内容,如果未能解决你的问题,请参考以下文章