我已经用C ++编写了一个Python模块,并将其构建为共享对象库,并且运行良好。但是在弄清所有问题的同时,我注意到(通过strace)Python会寻找一些不同的变体import。特别地,当我说时import foo,Python按顺序搜索:
import
import foo
除了foomodule.so以外,这一切都是可以理解的。为什么Python会同时以name.so和namemodule.so的形式查找所有内容?这是一些历史文物吗?我进行了很多搜索,并没有给出任何解释,并且想知道是否应该将模块命名为foomodule.so而不是foo.so。我的系统似乎在遵循每个约定的情况下已有一些现有的Python模块,因此我不禁想知道不同的名称是否暗示某些含义。
这实际上是依赖于平台的,Python根据操作系统尝试使用不同的后缀。这是后缀表的初始化import.c:
import.c
#ifdef HAVE_DYNAMIC_LOADING memcpy(filetab, _PyImport_DynLoadFiletab, countD * sizeof(struct filedescr)); #endif memcpy(filetab + countD, _PyImport_StandardFiletab, countS * sizeof(struct filedescr)); filetab[countD + countS].suffix = NULL; _PyImport_Filetab = filetab;
因此它加入了两个列表,_PyImport_DynLoadFiletab和_PyImport_StandardFiletab。后者比较容易,它被定义为[".py", ".pyw", ".pyc"]在同一文件中(第二个条目仅在Windows上存在)。_PyImport_DynLoadFiletab在各种dynload_<platform>.c文件中定义。在基于Unix的系统上,其值是[".so", "module.so"],对于CygWin则定义,[".dll", "module.dll"]而对于OS / 2则是,[".pyd", ".dll"]而对于Windows则简单[".pyd"]。
_PyImport_DynLoadFiletab
_PyImport_StandardFiletab
[".py", ".pyw", ".pyc"]
dynload_<platform>.c
[".so", "module.so"]
[".dll", "module.dll"]
[".pyd", ".dll"]
[".pyd"]
我仔细阅读了源代码的历史,最后从1999年开始进行了这一更改,该更改显然添加了“ module.so”作为可能的后缀: http://hg.python.org/cpython- fullhistory/diff/8efa37a770c6/Python/importdl。 c。因此,更改最初是为NeXTStep(最终成为Mac OS X)添加的,仅用于特定的链接设置。我不知道这个操作系统,所以很难说出它为什么要做- 我怀疑这仅仅是为了防止命名冲突。例如,一个框架库foo.so可能已经被加载,操作系统将不允许加载另一个具有相同名称的库。因此foomodule.so,允许使用名称foo仍然存在的Python模块是一种妥协。
foo.so
foomodule.so
foo
编辑 :上面的段落是错误的- 由于senderle指出了这一点,我在历史上做得还不够。实际上,有趣的变化似乎是1994年的http://hg.python.org/cpython- fullhistory/diff/2230/Python/import.c,其中添加了新的模块命名方案(foo.so)作为替代旧方案(foomodule.so)。我猜想由于考虑到在某些平台(例如Windows)中对该代码的大量重写之一,已经删除了对旧版本的支持,因此旧版本已过时。请注意,即使在首次引入时,短模块名称版本也被列在首位- 这意味着它已经是首选变量。
Edit2 :我搜索了1994年 以来 的邮件列表/新闻组,以查看是否在某处讨论了此更改-看起来不是这样,Guido van Rossum似乎是在未告知任何人的情况下实施了此更改。