我有一个工作服务,我需要在其中调试 Python 代码。要执行 Python 代码,我需要使用 Pythonnet。 Pdb模块用于调试。 我正在尝试类似的事情:
python.txt:
import pdb
def func():
pdb.set_trace()
//code for debugging...
C#代码:
var pythonCode = File.ReadAllText(@"D:\python.txt");
Runtime.PythonDLL = @"D:\Python38\python38.dll";
PythonEngine.Initialize();
using (Py.GIL())
{
var pyModule = Py.CreateScope("scope");
pyModule.Exec(pythonCode);
}
Task.Run(() =>
{
using (Py.GIL())
{
pyModule.Exec("func()");
}
});
//some code
在 Python 代码中,我调用
pdb.set_trace()
,它等待进一步的调试器命令(n(ext)、s(tep) 等)输入到控制台。
在 C# 代码中,我在不同的线程中执行 Python 函数,以免阻塞等待输入命令的服务主线程。如果我使用 VSCode 的内部控制台手动输入命令,它就可以工作。但我需要通过我的工作服务从 GUI 传递调试器命令。
如何将这些命令传递到以编程方式从服务执行 python 代码的标准输入?
我也有同样的问题。我想使用 pdb,但由于缺乏 I/O 流,很快就放弃了 PythonNet。我确实使用 Process 类型来运行 python.exe 以通过设置启动 python 控制台:
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = pythonExePath,
Arguments = "-u -i -q",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
pythonProcess = new Process() { StartInfo = psi };
pythonProcess.Start();
pythonProcess.BeginOutputReadLine();
pythonProcess.BeginErrorReadLine();
outputBuffer = new ConcurrentQueue<string>();
errorBuffer = new ConcurrentQueue<string>();
pythonProcess.OutputDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args.Data))
{
outputBuffer.Enqueue(args.Data);
}
};
pythonProcess.ErrorDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args.Data))
{
errorBuffer.Enqueue(args.Data);
}
};
它以交互模式运行,并且是无缓冲的。如果我直接使用控制台我可以这样做:
>>> breakpoint()
--Return--
> <stdin>(1)<module>()->None
(Pdb) s
>>>
然后我可以继续执行新命令。 如果我尝试使用 C# 中的 Process 重新创建它,我会得到:
breakpoint()
--Return--
> <stdin>(1)<module>()->None
s
s
(Pdb) (Pdb) --Call--
> c:...python\lib\encodings\cp1251.py(14)decode()
-> def decode(self,input,errors='strict'):
(Pdb) > c:...\python\lib\encodings\cp1251.py(15)decode()
-> return codecs.charmap_decode(input,errors,decoding_table)
(Pdb) --Return--
> c:...\python\lib\encodings\cp1251.py(15)decode()->('\ns\n', 3)
-> return codecs.charmap_decode(input,errors,decoding_table)
您看到的代码片段既是发送的输入,也是接收的输出。这里发送的唯一命令是“breakpoint()”、“s”和“s”。第一个“s”不会产生任何结果,只有在发送第二个“s”后我才会得到回复。
备注:
这是我的第一篇文章,如果不符合标准,请道歉。我将不胜感激任何帮助。