这实际上是与平台相关的,Python会根据操作系统尝试不同的后缀。以下是在
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"]
。
我查看了源代码历史记录,最终找到了这个1999年的更改,显然添加了"module.so"作为可能的后缀名:
http://hg.python.org/cpython-fullhistory/diff/8efa37a770c6/Python/importdl.c。因此,这些更改最初是为NeXTStep(最终成为Mac OS X)添加的,仅适用于特定的链接设置。我不了解这个操作系统,所以很难说为什么要这样做 - 我怀疑这只是为了防止命名冲突。例如,一个框架库
foo.so
可能已经被加载,操作系统不允许加载另一个同名的库。因此,
foomodule.so
是一种妥协,允许存在一个名为
foo
的Python模块。
编辑: 上面的段落是错误的 - 我没有回溯到足够早的历史,感谢senderle指出这一点。实际上,有趣的变化似乎出现在1994年的http://hg.python.org/cpython-fullhistory/diff/2230/Python/import.c,那时添加了一个新的模块命名方案(foo.so
)作为旧方案(foomodule.so
)的替代方案。我猜旧形式在某个时候变得不推荐使用,因为像Windows这样的一些平台已经删除了对它的支持,在该代码的众多重写之一中。请注意,即使在最初引入时,短模块名称版本也被列在首位,这意味着它已经是首选变体。
编辑2: 我搜索了1994年的邮件列表/新闻组,看看是否在某个地方讨论了这个变化 - 看起来没有,Guido van Rossum似乎在没有告诉任何人的情况下实施了它。
#define LONG_EXT "module.so"
的定义,那么它在你谈论的补丁之前很久就存在了。事实上,在importdl.c
创建时就已经存在了! - senderleimportdl.c
是在重写中创建的,原始代码可以在import.c
中找到 - 我找到了引入两种命名方案的更改并更新了我的答案。很遗憾,Python机构的记忆不包括导致变化的讨论。 - Wladimir Palant