让python -m模块用于在C中实现的模块

Rog*_*nns 10 python

我有一个用于Python的纯C模块,我希望能够使用该python -m modulename方法调用它.这适用于使用Python实现的模块,一个明显的解决方法是为此目的添加额外的文件.但是,我真的想保留一个单独的分布式二进制文件,而不是仅为此解决方法添加第二个文件.

我不在乎解决方案有多hacky.

如果您尝试使用带有-m的C模块,则会收到错误消息No code object available for <modulename>.

iva*_*eev 5

-m实施在runpy._run_module_as_main. 它的本质是:

mod_name, loader, code, fname = _get_module_details(mod_name)
<...>
exec code in run_globals
Run Code Online (Sandbox Code Playgroud)

已编译的模块没有与之相关的“代码对象”,因此第一个语句失败并带有ImportError("No code object available for <module>"). 您需要扩展 runpy - 特别是_get_module_details- 使其适用于已编译的模块。我建议返回一个从上述构造的代码对象"import mod; mod.main()":(python 2.6.1)

    code = loader.get_code(mod_name)
    if code is None:
+       if loader.etc[2]==imp.C_EXTENSION:
+           code=compile("import %(mod)s; %(mod)s.main()"%{'mod':mod_name},"<extension loader wrapper>","exec")
+       else:
+           raise ImportError("No code object available for %s" % mod_name)
-       raise ImportError("No code object available for %s" % mod_name)
    filename = _get_filename(loader, mod_name)
Run Code Online (Sandbox Code Playgroud)

(更新:修复了格式字符串中的错误)

现在...

C:\Documents and Settings\????????????>python -m pythoncom

C:\Documents and Settings\????????????>
Run Code Online (Sandbox Code Playgroud)

这仍然不适用于内置模块。同样,您需要为它们发明一些“主代码单元”的概念。

更新:

我已经查看了调用 from 的内部结构,_get_module_details并且可以自信地说,它们甚至不会尝试imp.PY_SOURCE, imp.PY_COMPILEDor以外类型的模块中检索代码对象imp.PKG_DIRECTORY。所以你必须以这种方式或另一种方式修补这个机器-m才能工作。Python从您的模块中检索任何内容之前失败(它甚至不检查 dll 是否是有效模块),因此您无法通过以特殊方式构建它来做任何事情。

  • 自这个答案创建以来已经快 8 年了。有谁知道我是否仍然需要制定解决方法来使用“-m”标志执行 cythonized 脚本?IE。`python -m app.module`? (2认同)