Python共享对象模块命名约定

时间:2011-06-12 00:31:02

标签: python module naming-conventions shared-libraries

我用C ++编写了一个Python模块,并将其构建为共享对象库,并且工作正常。但是在解决所有这些问题时,我注意到(通过strace)Python会查找一些不同的变体import。特别是,当我说import foo时,Python按顺序搜索:

  • foo(目录)
  • foo.so
  • foomodule.so
  • foo.py
  • foo.pyc

除了foomodule.so之外,这一切都是可以理解的。为什么Python会以name.so和namemodule.so的形式查找所有内容?这是一些历史文物吗?我搜索了很多,根本没有解释,我想知道我是否应该命名我的模块foomodule.so而不是foo.so.我的系统似乎在每个约定之后都有一些现有的Python模块,所以我不禁想知道不同的名字是否意味着什么。

2 个答案:

答案 0 :(得分:18)

这实际上是依赖于平台的,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模块存在的妥协。

编辑:上面的段落错了 - 我在历史上没有做得足够多,感谢发送者指出了这一点。事实上,从1994年开始,有趣的变化似乎是http://hg.python.org/cpython-fullhistory/diff/2230/Python/import.c,这是新模块命名方案(foo.so)被添加为旧方案(foomodule.so)的替代方案。我猜这个旧表格在某些时候已经被弃用了,因为对于某些平台,例如Windows中的一个平台,在该代码的众多重写之一中已经删除了对它的支持。请注意,即使首次引入,也会首先列出短模块名称版本 - 这意味着它已经是首选变体。

Edit2 :我从1994年搜索了邮件列表/新闻组,看看这个变化是否在某个地方被讨论过 - 看起来不像是这样,Guido van Rossum似乎已经实现了它而没有告诉任何人

答案 1 :(得分:10)

这只是猜测,但我只能假设这与下面的Extending Python with C or C++相关。

  

首先创建一个文件spammodule.c。 (从历史上看,如果模块被称为垃圾邮件,则包含其实现的C文件称为spammodule.c;如果模块名称非常长,如spammify,则模块名称可能只是spammify.c。)

我认为这个约定扩展到.so文件的名称。 the same的第1.5节进一步支持了这一猜想。


根据Wladimir的excellent discovery,我发现first referencemodule.so作为后缀。它来自一个补丁,支持动态加载SunOS库,来自“Bill”。 (Bill Jansson?)显然,module - as-suffix约定在使用.so共享库之前开始,并且当采用.so库时,简单地维护了约定。 / p>

我认为弗拉迪米尔是正确的 - 有趣的变化是采用短模块名称惯例的变化。这证实了我的猜测,长模块名称是早期的惯例。