我有一个用于Python的纯C模块,我希望能够使用该python -m modulename方法调用它.这适用于使用Python实现的模块,一个明显的解决方法是为此目的添加额外的文件.但是,我真的想保留一个单独的分布式二进制文件,而不是仅为此解决方法添加第二个文件.
我不在乎解决方案有多hacky.
如果您尝试使用带有-m的C模块,则会收到错误消息No code object available for <modulename>.
-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 是否是有效模块),因此您无法通过以特殊方式构建它来做任何事情。