扩展python中的AttributeError与C / C ++

时间:2013-08-27 11:22:50

标签: c++ python swig distutils attributeerror

我在使用简单的C文件扩展python时遇到了问题。

hello.c源代码:

#include <Python.h>

static PyObject* say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    printf("Hello %s!\n", name);

    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] =
{
     {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
     {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inithello(void)
{
     (void) Py_InitModule("hello", HelloMethods);
}

setup.py:

from distutils.core import setup, Extension

module1 = Extension('hello', sources = ['hello.c'])

setup (name = 'PackageName',
       version = '1.0',
       packages=['hello'],
       description = 'This is a demo package',
       ext_modules = [module1])

我还在“hello”文件夹中创建了空文件“__init__.py”。

在调用“python setup.py build”之后我可以导入你好,但是当我尝试时 使用“hello.say_hello()”我面对错误:

追踪(最近一次通话):   文件“&lt; stdin&gt;”,第1行,in AttributeError:'module'对象没有属性'say_hello'

如果有人能帮我找到解决方案,我很感激。

由于

1 个答案:

答案 0 :(得分:1)

您正在导入包而不是扩展程序:

$python2 hello_setup.py build
running build
running build_py
# etc.
$cd build/lib.linux-x86_64-2.7/
$ls
hello  hello.so
$python
Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>> hello
<module 'hello' from 'hello/__init__.py'>

如果要导入扩展程序hello.so,则必须重命名该扩展程序,或将其放在程序包下。在这种情况下,您可以使用from hello import hello导入它:

$mv hello.so hello
$python2
Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from hello import hello
>>> hello
<module 'hello.hello' from 'hello/hello.so'>
>>> hello.say_hello("World!")
Hello World!!

我没有看到有一个只包含一个扩展模块的软件包的原因。 我只是使用更简单的设置摆脱包装:

from distutils.core import setup, Extension

module1 = Extension('hello', sources=['hello.c'])

setup(name='MyExtension',
       version='1.0',
       description='This is a demo extension',
       ext_modules=[module1])

这只会产生hello.so库,您可以这样做:

>>> import hello

导入扩展程序。

一般建议:避免使用多个具有相同名称的模块/包。 有时很难分辨哪个模块是导入的(如你的情况)。 此外,当使用不同的名称而不是导入错误的模块并获得奇怪的错误时,如果出现问题,您将看到ImportError,这指出了究竟缺少的内容。