简体   繁体   中英

AttributeError in extension python with C/C++

I have a problem with extending python with a simple C file.

hello.c source code:

#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])

I also created empty file "__init__.py" in the folder "hello".

After calling "python setup.py build" I could import hello, but when I try to use "hello.say_hello()" I face with the error:

Traceback (most recent call last): File "< stdin>", line 1, in AttributeError: 'module' object has no attribute 'say_hello'

I appreciate if somebody can help me to find the solution.

Thanks

Your are importing the package instead of the extension:

$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'>

If you want to import the extension, hello.so , then you have to either rename it, or put it under the package. In which case you can use from hello import hello to import it:

$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!!

I don't see the reason to have a package that only contains a single extension module. I'd simply get rid of the package using a simpler setup:

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])

This will only produce the hello.so library, and you can simply do:

>>> import hello

To import the extension.

General advice: avoid having more than one module/package with the same name. Sometimes it's hard to tell which module is imported(as in your case). Also, when using different names instead of importing the wrong module and getting weird bugs you'll see an ImportError if something is wrong, which points out what exactly is missing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM