2014-02-19 189 views
2

我写了一个样本学习Python,但是当呼叫PyObject_IsInstance,此函数始终返回0 这里是我的C代码ReadBuf.c为什么PyObject_IsInstance总是在我的示例代码返回0

#include "Python.h" 

static PyObject* Test_IsInstance(PyObject* self, PyObject* args){ 
    PyObject* pyTest = NULL; 
    PyObject* pName = NULL; 
    PyObject* moduleDict = NULL; 
    PyObject* className = NULL; 
    PyObject* pModule = NULL; 

    pName = PyString_FromString("client"); 
    pModule = PyImport_Import(pName); 
    if (!pModule){ 
     printf("can not find client.py\n"); 
     Py_RETURN_NONE; 
    } 

    moduleDict = PyModule_GetDict(pModule); 
    if (!moduleDict){ 
     printf("can not get Dict\n"); 
     Py_RETURN_NONE; 
    } 

    className = PyDict_GetItemString(moduleDict, "Test"); 
    if (!className){ 
     printf("can not get className\n"); 
     Py_RETURN_NONE; 
    } 
    /* 
    PyObject* pInsTest = PyInstance_New(className, NULL, NULL); 
    PyObject_CallMethod(pInsTest, "py_print", "()"); 
    */ 
    int ok = PyArg_ParseTuple(args, "O", &pyTest); 
    if (!ok){ 
     printf("parse tuple error!\n"); 
     Py_RETURN_NONE; 
    } 
    if (!pyTest){ 
     printf("can not get the instance from python\n"); 
     Py_RETURN_NONE; 
    } 
    /* 
    PyObject_CallMethod(pyTest, "py_print", "()"); 
    */ 
    if (!PyObject_IsInstance(pyTest, className)){ 
     printf("Not an instance for Test\n"); 
     Py_RETURN_NONE; 
    } 
    Py_RETURN_NONE; 
} 
static PyMethodDef readbuffer[] = { 
    {"testIns", Test_IsInstance, METH_VARARGS, "test for instance!"}, 
    {NULL, NULL} 
}; 

void initReadBuf(){ 

    PyObject* m; 
    m = Py_InitModule("ReadBuf", readbuffer); 
} 

而下面是我的Python代码client.py

#!/usr/bin/env python 
import sys 
import ReadBuf as rb 

class Test: 
    def __init__(self): 
    print "Test class" 
    def py_print(self): 
    print "Test py_print" 

class pyTest(Test): 
    def __init__(self): 
    Test.__init__(self) 
    print "pyTest class" 
    def py_print(self): 
    print "pyTest py_print" 

b = pyTest() 
rb.testIns(b) 

我通过b,其是pyTest至C的实例,它是由PyArg_ParseTuple解析以pyTest。运行PyObject_IsInstance时,结果总是为零,这意味着pyTest不是Test的一个实例。 我的问题: 当从python传递参数到C时,类型是否改变?如果我想比较一下,如果pyTest是Test的一个实例,我应该怎么做?

谢谢, 瓦岱勒

回答

1

client模块未完全装入时的延伸尝试加载client模块.;执行client发生两次(仔细观察输出)。

所以Testclient.pyTest中的扩展模块引用的是不同的对象。

您可以通过提取分离模块中的类来解决此问题。 (说common.py)并在client.py和扩展模块中导入common

参见a demo

+0

感谢falsetru,非常有帮助。我确实看到了输出两次的东西。还有一个问题,你提到客户端的导入发生了两次,为什么发生这种情况?我只在ReadBuf.c中导入一次客户端。当我执行python client.py时,客户端又导入了另外一次吗?谢谢, – Vatel

+0

@Vatel,我的意思是'执行'。修正了这个词。 1.执行一次,因为它是由程序运行调用的。当它调用'testIns'函数时,模块没有被完全加载。 (因为'client.py'中的所有语句都没有执行,所以没有注册为'sys.modules')。 2.由扩展模块导入。所以它被执行两次。 – falsetru

+0

是的,当我只导入了common,并且使用dir(common)进行检查时,没有名为Test的属性。所以pyTest在执行时加载1),而测试在执行时加载2)。感谢您的帮助。 – Vatel

相关问题