2014-02-19 4 views
2

Я пишу образец, чтобы узнать, питона, но когда вызов PyObject_IsInstance, эта функция всегда возвращает 0. Вот мой код с 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) 

Перехожу б, который является экземпляром pyTest с, и анализируется с помощью PyArg_ParseTuple к pyTest. При запуске PyObject_IsInstance результат всегда равен нулю, что означает, что pyTest не является экземпляром Test. Мой вопрос: Когда параметр pass от python до C, является ли тип изменен? Как мне сделать, если я хочу сравнить это, если pyTest является экземпляром Test?

Спасибо, Ватель

ответ

1

Модуль client не был полностью загружен, когда расширение пытаться загрузить модуль client .; Выполнение client происходит дважды (внимательно следите за выходом).

Так Test в client.py и Test в модуле расширения ссылаются на разные объекты.

Вы можете обойти это, извлекая классы в отдельный модуль. (Скажите common.py) И импортируйте common как в client.py, так и в модуль расширения.

См. a demo.

+0

Спасибо falsetru, очень полезно. Я дважды видел результат. Еще один вопрос, вы упомянули, что импорт клиента происходит дважды, почему это произошло? Я просто импортирую клиент один раз в ReadBuf.c. Является ли клиент импортированным в другое время, когда я выполняю python client.py? Спасибо, – Vatel

+0

@Vatel, я имел в виду 'исполнение'. Исправлено слово. 1. выполняется один раз, потому что он вызывается запуском программы. в то время как он вызывает функцию 'testIns', модуль не полностью загружен. (потому что все утверждения в 'client.py' не выполняются, поэтому пока не регистрируется в' sys.modules'). 2. импортируется модулем расширения. Так что он выполняется дважды. – falsetru

+0

Да, когда я только импортировал общий и использовал dir (common) для проверки, нет атрибута Test. Таким образом, pyTest был загружен во время выполнения 1), а Test был загружен во время выполнения 2). Спасибо за вашу любезную помощь. – Vatel

 Смежные вопросы

  • Нет связанных вопросов^_^