当我使用 Cython 编译使用 Python.NET 访问 .NET 程序集的 Python 代码时,它找不到这些程序集:
ModuleNotFoundError: No module named 'System'
无需编译即可正常工作。
对于演示代码,我使用了 https://github.com/pythonnet/pythonnet/blob/master/demo/helloform.py
我的setup.py
文件:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules = [
Extension(
'helloform',
sources = ['helloform.py'],
language = 'c++'
)
]
setup(
name = 'helloform',
ext_modules = cythonize(ext_modules),
)
然后我用python setup.py build_ext --inplace
构建它.
我想用import helloform
从 Python 提示符加载编译的模块,但它失败了
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "helloform.py", line 8, in init helloform
ModuleNotFoundError: No module named 'System'
这个答案未经测试——我认为我不能轻易地设置一个环境来测试,所以这只是一个猜测。如果它不起作用,我会删除它。
这可能是一个错误,如果您希望长期修复它,您应该报告它。Cython确实尽可能尝试与Python兼容。快速调查表明,Python.NET 会覆盖内置的__import__
函数。Cython 希望在 Python 2 中查找并使用此函数,但在 Python 3 中则不然。这不再是自定义导入行为的首选方法(但仍受支持)。我猜它会在 Cython + Python 2 中工作吗?
作为一种解决方法,您可能应该只在 Python 中运行导入语句。有两种明显的方法可以做到这一点:
-
编写一个只包含导入语句的单独小模块,然后在 Cython 中从该模块导入:
from import_module import WinForms, Size, Point
-
运行
exec
中的导入语句;从您传递给它的全局字典中提取值:import_dict = {} exec("""import clr # etc... """, import_dict) # pass a dict in as `globals` WinForms = import_dict['WinForms'] # etc.