如何使用setuptools创建包含多个模块的python包?

时间:2014-08-04 21:52:12

标签: python setuptools

我想组织一个包含多个模块的发行版。最终将有一个C扩展模块,并在同一'级别',几个纯python模块。我不确定顶层是否应该被视为命名空间。

对于初学者,我想创建一个模块monty.spam。它将是C扩展。我把它从Extending Python docs.

中取出来了

蒙蒂/垃圾邮件/ spammodule.c

#include <Python.h>

static PyObject * spam_system (PyObject * self, PyObject * args)
  {
  const char * command;
  int          sts;

  if (!PyArg_ParseTuple (args, "s", &command))
    return NULL;
  sts = system (command);
  return Py_BuildValue ("i", sts);
  }

static 
PyMethodDef SpamMethods [] = {
             { "system", spam_system, METH_VARARGS, "Execute a shell command" },
             { NULL, NULL, 0, NULL }    
             };

PyMODINIT_FUNC
initspam (void)
  {
  (void) Py_InitModule ("spam", SpamMethods);
  }

我在同一目录下创建了一个安装工具setup.py,运行了“python setup.py develop”,模块工作正常。

蒙蒂/垃圾邮件/ setup.py

from setuptools import setup, Extension

module = Extension ('spam', sources = [ 'spammodule.c' ])

setup (
      name = 'MontyP',
      version = '0.2', 
      description = 'pure spam',
      ext_modules = [ module ]
      )

在monty目录中:

python -c 'import monty.spam'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named monty.spam

所以现在我想创建一个垃圾邮件“存在”monty的发行版。我在monty目录中尝试了一些setup.py它们的变种。 (两个目录都有一个空的__init__.py

我在monty / setup.py上的最新尝试:(是的,find_packages()在这个版本中没有实用程序。)

from setuptools import setup, Extension, find_packages

module = Extension ('spam', sources = [ './spam/spammodule.c' ])

print find_packages ()
setup (
      name               = 'MontyP',
      version            = '0.2', 
      namespace_packages = [ 'monty' ],
      packages           = find_packages (),
      description        = 'pure spam',
      ext_modules        = [ module ]
      )

没有欢乐!

python setup.py develop
['spam']
error in MontyP setup command: Distribution contains no modules or packages for namespace package 'monty'

1 个答案:

答案 0 :(得分:1)

您只需要进行两到三次更改即可。

首先,monty/spam不应放在setup.py,而应放在与monty/相同的级别:

enter image description here

setup.py总是在项目的根目录中。

另外,在__init__.py中创建一个monty文件,但在__init__.py 中创建spam

现在,在setup.py的“module = Extension ('spam', sources = [ 'spammodule.c' ])”行中,将spam替换为monty.spam,将spammodule.c替换为monty/spam/spammodule.c

module = Extension ('monty.spam', sources = [ 'monty/spam/spammodule.c' ])

这是必要的,因为外部模块应使用其全名声明(monty.spam而不是spam)。此外,由于现在setup.py位于项目的根目录中,因此它应该会收到C源文件的相对但完整的路径。

就是这样,你的模块现在应该可以工作了。