【问题标题】:Why PyObject_IsInstance always return 0 in my sample code为什么 PyObject_IsInstance 在我的示例代码中总是返回 0
【发布时间】:2014-03-19 09:38:20
【问题描述】:

我写了一个例子来学习python,但是调用PyObject_IsInstance时,这个函数总是返回0。 这是我的 c 代码 ReadBuf.c

#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 实例的 b 传递给 C,并由 PyArg_ParseTuple 解析给 pyTest。运行 PyObject_IsInstance 时,结果始终为零,这意味着 pyTest 不是 Test 的实例。 我的问题: 当从 python 传递参数到 C 时,类型是否改变了?如果 pyTest 是 Test 的一个实例,如果我想比较,我应该怎么做?

谢谢, 瓦特尔

【问题讨论】:

    标签: python c python-extensions isinstance


    【解决方案1】:

    当扩展尝试加载client 模块时,client 模块未完全加载。 client 执行了两次(仔细观察输出)。

    所以client.py 中的Test 和扩展模块中的Test 引用了不同的对象。

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

    a demo

    【讨论】:

    • 感谢 falsetru,非常有帮助。我确实看到了两次输出。还有一个问题,您提到客户端的导入发生了两次,为什么会发生这种情况?我只在 ReadBuf.c 中导入一次客户端。当我执行 python client.py 时,客户端是否再次导入?谢谢,
    • @Vatel,我的意思是execution。修正了这个词。 1. 执行一次,因为它被程序运行调用。当它调用testIns 函数时,模块没有完全加载。 (因为client.py中的所有语句都没有执行,所以还没有注册到sys.modules)。 2.由扩展模块导入。所以它被执行了两次。
    • 是的,当我只导入common,并使用dir(common)检查时,没有名为Test的属性。所以 pyTest 在执行 1) 时被加载,而 Test 在执行 2) 时被加载。感谢您的热心帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 2020-05-25
    • 2013-02-26
    • 2013-06-25
    相关资源
    最近更新 更多