Linux下.NET Core通过pythonnet调用python-apt的apt.Cache报错及调试咨询
解决方案
一、_system not initialized报错修复
错误原因
- 代码中导入了底层模块
apt_pkg而非上层封装apt模块,apt_pkg作为底层绑定需要手动完成系统初始化操作才能调用相关接口,直接调用Cache()方法就会触发该报错 - 直接将
Cache返回的类字典对象强转为PyDict类型会出现类型转换错误,apt.Cache并非原生Python字典,仅实现了字典的访问接口,需用PyObject接收
修复后的VB.NET代码
Runtime.PythonDLL = "/usr/lib/python3.9/config-3.9-x86_64-linux-gnu/libpython3.9.so" Python.Runtime.PythonEngine.PythonHome = "/usr/lib/python3.9" PythonEngine.Initialize() Using Py.GIL ' 导入正确的apt模块而非apt_pkg Dim apt As PyObject = Py.Import("apt") ' 用PyObject接收类字典的Cache对象,不要强转PyDict Dim cache As PyObject = apt.Cache() ' 遍历所有包名示例 Dim pkgNames As PyObject = cache.keys() For Each name In pkgNames Console.WriteLine(name.ToString()) Next End Using
若确实需要直接使用apt_pkg模块,需先执行初始化操作:
Using Py.GIL Dim apt_pkg As PyObject = Py.Import("apt_pkg") ' 手动完成底层初始化 apt_pkg.init_config() apt_pkg.init_system() Dim cache As PyObject = apt_pkg.Cache() End Using
C#版本参考代码
Runtime.PythonDLL = "/usr/lib/python3.9/config-3.9-x86_64-linux-gnu/libpython3.9.so"; Python.Runtime.PythonEngine.PythonHome = "/usr/lib/python3.9"; PythonEngine.Initialize(); using (Py.GIL()) { dynamic apt = Py.Import("apt"); dynamic cache = apt.Cache(); foreach (var pkgName in cache.keys()) { Console.WriteLine(pkgName.ToString()); } }
二、Visual Studio调试查看Python模块成员方法
无需IntelliSense支持,可通过以下方式查看成员:
- 调试时在断点处查看
PyObject的非公共成员中的__dict__属性,里面包含该对象所有属性和方法的键值对 - 临时在代码中调用Python内置的
dir()方法获取所有成员列表,调试时可直接查看返回的集合内容,示例代码:' 获取apt模块的所有成员 Dim dirFunc As PyObject = PythonEngine.Eval("dir") Dim aptMembers As PyObject = dirFunc.Invoke(apt) ' 调试时查看aptMembers即可看到所有成员名称 - 使用
dynamic类型声明Python对象,调试时VS会自动枚举动态对象的所有成员显示在监视窗口中。
内容的提问来源于stack exchange,提问作者MrCalvin
相关产品推荐
相关产品推荐

