将 stdout/stderr 从嵌入在 .NET 应用程序中的 Python 重定向到文本框
Redirect stdout/stderr from Python embedded in .NET application to text box
我正在尝试使用 Python.NET.
在 C# Windows Forms 应用程序中嵌入交互式 Python shell
我能够将解释器嵌入我的 C# 应用程序并从 .NET 访问 Python 模块。我现在正在尝试将 Python 解释器的输出和错误重定向到 .NET 文本框。虽然我能够将标准输出重定向到一个文件,但我在将输出路由到文本框时遇到了问题。
这是我目前尝试过的:
想法是将 Python 的 sys.stdout 分配给一个 .NET 对象,该对象实现与 python 流相同的接口(write()、writelines()...):
.NET class 模仿 Python 流:
public class TextBoxStream : PyObject // To assign to sys.stdout. Is this correct?
{
private TextBox _output = null;
public TextBoxStream() {}
public TextBoxStream(TextBox output)
{
_output = output;
}
void write(object value)
{
_output.AppendText(value.ToString());
}
void writelines(object value)
{
}
}
在Form1.cs中:
private void button1_Click(object sender, EventArgs e)
{
using (Py.GIL())
{
// Redirect stdout to text box
dynamic sys = PythonEngine.ImportModule("sys");
TextBoxStream textBoxStream = new TextBoxStream(textBox1);
sys.stdout = textBoxStream;
//sys.SetAttr("stdout", textBoxStream); // This did not work either
string code =
"import sys\n" +
"print 'Message 1'\n" +
"sys.stdout.write('Message 2')\n" +
"sys.stdout.flush()";
PyObject redirectPyObj = PythonEngine.RunString(code); // NULL
sys.stdout.write("Message 3");
// Exception thrown: 'Python.Runtime.PyObject' does not contain a definition for 'stdout'
}
}
这也不起作用:redirectPyObj 为 NULL。我尝试使用旧的和新的 Python.NET API (动态)。 sys.stdout.write 和 print 语句都不会写入文本框。
关于如何解决这个问题的任何想法都会非常有帮助。
对我有用的解决方案是将 Python stdout/stderr 重定向到 Python 中的流。然后我能够将此流路由到 .NET 文本框中。
private void button1_Click(object sender, EventArgs e)
{
using (Py.GIL())
{
// Redirect stdout to text box
dynamic sys = PythonEngine.ImportModule("sys");
string codeToRedirectOutput =
"import sys\n" +
"from io import StringIO\n" +
"sys.stdout = mystdout = StringIO()\n" +
"sys.stdout.flush()\n" +
"sys.stderr = mystderr = StringIO()\n" +
"sys.stderr.flush()\n";
PythonEngine.RunString(codeToRedirectOutput);
// Run Python code
string pyCode = "print(1 + 2)";
PyObject result = PythonEngine.RunString(pyCode); // null in case of error
if (result != null)
{
string pyStdout = sys.stdout.getvalue(); // Get stdout
pyStdout = pyStdout.Replace("\n", "\r\n"); // To support newline for textbox
textBox1.Text = pyStdout;
}
else
{
PythonEngine.PrintError(); // Make Python engine print errors
string pyStderr = sys.stderr.getvalue(); // Get stderr
pyStderr = pyStderr.Replace("\n", "\r\n"); // To support newline for textbox
textBox1.Text = pyStderr;
}
}
}
使用此代码,我能够将 Python 引擎的 stdout(和错误情况下的 stderr)重定向到 .NET 文本框。
我正在尝试使用 Python.NET.
在 C# Windows Forms 应用程序中嵌入交互式 Python shell我能够将解释器嵌入我的 C# 应用程序并从 .NET 访问 Python 模块。我现在正在尝试将 Python 解释器的输出和错误重定向到 .NET 文本框。虽然我能够将标准输出重定向到一个文件,但我在将输出路由到文本框时遇到了问题。
这是我目前尝试过的: 想法是将 Python 的 sys.stdout 分配给一个 .NET 对象,该对象实现与 python 流相同的接口(write()、writelines()...):
.NET class 模仿 Python 流:
public class TextBoxStream : PyObject // To assign to sys.stdout. Is this correct?
{
private TextBox _output = null;
public TextBoxStream() {}
public TextBoxStream(TextBox output)
{
_output = output;
}
void write(object value)
{
_output.AppendText(value.ToString());
}
void writelines(object value)
{
}
}
在Form1.cs中:
private void button1_Click(object sender, EventArgs e)
{
using (Py.GIL())
{
// Redirect stdout to text box
dynamic sys = PythonEngine.ImportModule("sys");
TextBoxStream textBoxStream = new TextBoxStream(textBox1);
sys.stdout = textBoxStream;
//sys.SetAttr("stdout", textBoxStream); // This did not work either
string code =
"import sys\n" +
"print 'Message 1'\n" +
"sys.stdout.write('Message 2')\n" +
"sys.stdout.flush()";
PyObject redirectPyObj = PythonEngine.RunString(code); // NULL
sys.stdout.write("Message 3");
// Exception thrown: 'Python.Runtime.PyObject' does not contain a definition for 'stdout'
}
}
这也不起作用:redirectPyObj 为 NULL。我尝试使用旧的和新的 Python.NET API (动态)。 sys.stdout.write 和 print 语句都不会写入文本框。
关于如何解决这个问题的任何想法都会非常有帮助。
对我有用的解决方案是将 Python stdout/stderr 重定向到 Python 中的流。然后我能够将此流路由到 .NET 文本框中。
private void button1_Click(object sender, EventArgs e)
{
using (Py.GIL())
{
// Redirect stdout to text box
dynamic sys = PythonEngine.ImportModule("sys");
string codeToRedirectOutput =
"import sys\n" +
"from io import StringIO\n" +
"sys.stdout = mystdout = StringIO()\n" +
"sys.stdout.flush()\n" +
"sys.stderr = mystderr = StringIO()\n" +
"sys.stderr.flush()\n";
PythonEngine.RunString(codeToRedirectOutput);
// Run Python code
string pyCode = "print(1 + 2)";
PyObject result = PythonEngine.RunString(pyCode); // null in case of error
if (result != null)
{
string pyStdout = sys.stdout.getvalue(); // Get stdout
pyStdout = pyStdout.Replace("\n", "\r\n"); // To support newline for textbox
textBox1.Text = pyStdout;
}
else
{
PythonEngine.PrintError(); // Make Python engine print errors
string pyStderr = sys.stderr.getvalue(); // Get stderr
pyStderr = pyStderr.Replace("\n", "\r\n"); // To support newline for textbox
textBox1.Text = pyStderr;
}
}
}
使用此代码,我能够将 Python 引擎的 stdout(和错误情况下的 stderr)重定向到 .NET 文本框。