您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在Python中,如何分辨模块是否来自C扩展?

在Python中,如何分辨模块是否来自C扩展?

首先,我认为这根本没有用。模块通常是围绕C扩展模块的纯Python包装,或者在某些情况下(如果有)围绕C扩展模块的纯Python包装,或者如果不存在,则是纯Python的实现。

对于一些流行的第三方示例:numpy是纯Python,即使所有重要的事情都用C实现了;bintrees是纯Python,即使其类可以全部用C或Python实现,具体取决于您如何构建它。等等

从3.2开始的大多数stdlib中都是如此。例如,如果您只是import pickle,则实现类将cpicklecpython中用C构建(您以前从2.7中获取),而它们在PyPy中将是纯Python版本,但无论哪种方式,pickle其本身都是纯Python。

但是,如果您 确实 想这样做,则实际上需要区分 件事:

假设您只关心cpython;如果您的代码在Jython或IronPython中运行,则实现可以是JVM或.NET,而不是本机代码

__file__由于多种原因,您无法基于完美区分。

在3.1及更高版本中,导入过程已被大量清理,大部分用Python重写,并且大部分暴露于Python层。

因此,您可以使用importlib模块查看用于加载模块的加载程序链,最终您将获得BuiltinImporterExtensionFileLoaderbuildins ),(。so / .pyd / etc。),SourceFileLoader(。py )或SourcelessFileLoader(.pyc /.pyo)。

您还可以在当前目标平台上看到分配给这四个变量的后缀,作为中的常量importlib.machinery。因此,您 可以 检查一下any(pathname.endswith(suffix) for suffix in importlib.machinery.EXTENSION_SUFFIXES)),但实际上并没有帮助,例如,除非您已经沿着链条向上旅行,否则在鸡蛋/拉链盒中也没有帮助。

任何人为此提出的最佳启发式方法都是在inspect模块中实现的,因此最好的办法就是使用它。

最好的选择将是一个或多个getsourcegetsourcefilegetfile; 最好取决于您想要的启发式方法

内置模块将为其中TypeError任何一个引发一个

扩展模块应为返回空字符串getsourcefile。这似乎适用于我所有的2.5-3.4版本,但是我没有2.4版本。对于getsource(至少在某些版本中),即使它应该返回一个空字符串或引发一个.so文件,它也将返回.so文件的实际字节IOError。(在3.x中,您几乎肯定会得到UnicodeErrororSyntaxError,但是您可能不想依赖它……)

getsourcefile如果在egg / zip / etc中,纯python模块可能会返回一个空字符串。getsource如果源可用,即使在egg / zip / etc等内部,它们也应始终返回非空字符串,但是,如果它们是无源字节码(.pyc / etc。),则它们将返回空字符串或引发IOError。

最好的选择是在您关心的发行版/安装程序中,在您关心的平台上试验您关心的版本。

python 2022/1/1 18:28:08 有187人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶