我正在尝试使用 Python.NET 在 C# Windows 窗体应用程序中嵌入交互式 Python shell .
我能够将解释器嵌入我的 C# 应用程序并从 .NET 访问 Python 模块。我现在正尝试将输出和错误从 Python 解释器重定向到 .NET 文本框。虽然我能够将标准输出重定向到一个文件,但我在将输出路由到文本框时遇到了问题。
这是我目前尝试过的: 这个想法是将 Python 的 sys.stdout 分配给一个 .NET 对象,该对象实现与 python 流相同的接口(interface)(write()、writelines()...):
.NET 类模仿 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 文本框。
关于c# - 将 stdout/stderr 从 .NET 应用程序中嵌入的 Python 重定向到文本框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37289082/