在C/C++扩展python AttributeError

问题描述:

我有一个简单的C文件扩展python的问题。在C/C++扩展python AttributeError

的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” 。

叫“蟒蛇的setup.py建”后,我可以导入打招呼,但是当我尝试使用 “hello.say_hello()”我面对的错误:

回溯(最近通话最后一个): 文件“<标准输入>”,1号线,在 AttributeError的:“模块”对象有“say_hello”

没有属性我很感激,如果有人可以帮我找到解决方案。

感谢

你导入的包,而不是扩展:

$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,该错误指出缺少的是什么。