2013-08-27 74 views
1

我有一個簡單的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」

沒有屬性我很感激,如果有人可以幫我找到解決方案。

感謝

回答

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,該錯誤指出缺少的是什麼。