【问题标题】:AttributeError in extension python with C/C++使用 C/C++ 扩展 python 中的 AttributeError
【发布时间】:2013-08-27 11:22:49
【问题描述】:

我在使用简单的 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()”我会遇到错误:

Traceback(最近一次调用最后一次): 文件“”,第 1 行,在 AttributeError: 'module' 对象没有属性 'say_hello'

如果有人可以帮助我找到解决方案,我将不胜感激。

谢谢

【问题讨论】:

    标签: c++ python swig distutils attributeerror


    【解决方案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,它指出了究竟缺少什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-07
      • 2017-06-11
      • 2021-09-27
      • 2012-01-05
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多