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