2014-02-19 242 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

相關問題