首页 > 解决方案 > Cythonized python.net 代码找不到系统程序集

问题描述

当我编译使用 python.net 访问 .Net 程序集的 python 代码时,它找不到这些程序集。没有编译它工作正常。

对于演示代码,我使用了 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.

我想从 Python 提示符加载已编译的模块,import helloform但它失败了

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "helloform.py", line 8, in init helloform
ModuleNotFoundError: No module named 'System'

标签: cythonpython.net

解决方案


这个答案是未经测试的——我认为我不能轻易地设置一个环境来测试,所以这有点猜测。如果它不起作用,我会删除它。

这可能是一个错误,如果您希望长期修复它,您应该报告它。Cython 确实尽可能地尝试与 Python 兼容......快速调查表明Python.NET 覆盖了内置__import__函数。Cython希望在 Python 2 中查找和使用此函数,但在 Python 3 中没有。这不再是自定义导入行为的首选方式(但仍受支持)。我猜它会在 Cython + Python 2 中工作?

作为一种解决方法,您可能应该只在 Python 中运行导入语句。有两种明显的方法可以做到:

  1. 编写一个仅包含导入语句的小型单独模块,然后在 Cython 中从该模块导入:

    from import_module import WinForms, Size, Point
    
  2. exec在;中运行导入语句 从您传递的全局字典中提取值:

    import_dict = {}
    exec("""import clr
    # etc...
    """, import_dict) # pass a dict in as `globals`
    WinForms = import_dict['WinForms']
    # etc.
    

推荐阅读