我在使用简单的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'
如果有人能帮我找到解决方案,我很感激。
由于
答案 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
,这指出了究竟缺少的内容。