es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué PyCallable_Check() devuelve 0 en instancias de clase global?

Actualmente estoy trabajando en la integración de Python en una aplicación más grande de C++. A pesar de que no soy un especialista en Python, entiendo que con la función integrada PyCallable_Check() puedo comprobar si un objeto de Python es realmente callable. De https://stackoverflow.com/questions/111234/what-is-a-callable descubrí que esto depende de la disponibilidad de un método __call__ dentro de las clases o en los tipos que tienen un miembro tp_call no nulo.

Lo que me preocupa ahora es que si tengo una referencia a un objeto (en C++) a una instancia global específica de alguna clase (dentro del script de Python), PyCallable_Check() me da un valor de retorno de 0 al comprobar esta referencia, incluso cuando realmente puedo llamarlo. Y dado que esto es posible, supondría tener un miembro tp_call aquí (como no tengo ningún método __call__ en mi ejemplo).

¿Entonces qué me falta? ¿Por qué obtengo un valor de retorno de 0?

Ejemplo de fragmento de C++:

//…

PyObject* pModule = PyImport_Import( PyUnicode_DecodeFSDefault(“testfile”) );
PyObject* pGlobalObj = PyObject_GetAttrString( pModule, “globalObj” );

int ok = PyCallable_Check(pGlobalObj);
if( !ok )
{
std::cerr << “¿No es callable?!” << std::endl;
std::cerr << “PyCallable_Check() da: ” << ok << std::endl;
}
//de todas formas, llamando al método de clase…
PyObject* pValue = PyObject_CallMethod( pGlobalObj , “add”, “(ii)”, 45, 55 );
std::cout << “Resultado del objeto global: ” << PyLong_AsLong(pValue) << std::endl;

//…

con el siguiente testfile.py:

class TestClass:
def add(self, a, b):
return a + b

globalObj = TestClass()

que da como resultado:

¿No es callable?!
PyCallable_Check() da: 0
Resultado del objeto global: 100

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que en su caso, la referencia del objeto pGlobalObj no es realmente un objeto callable, a pesar de poder llamarlo con éxito. Esto podría deberse a varias razones, como el objeto no tener un miembro tp_call o la función PyCallable_Check() no ser capaz de detectar correctamente el tipo de objeto.

    Una posible solución es usar una función más específica para verificar la capacidad de ser llamado, como PyFunction_Check() o PyMethod_Check(), dependiendo del tipo de objeto esperado. Otra opción es intentar llamar el objeto usando PyObject_CallObject() en lugar de PyObject_CallMethod(), lo que evitaría la verificación de la capacidad de ser llamado por completo y simplemente intentaría llamar el objeto como una función.

    En cualquier caso, es importante tener en cuenta que la capacidad de ser llamado puede ser un concepto complejo en Python, especialmente cuando se trata de objetos que tienen métodos __call__ personalizados u otros atributos especiales. Puede ser útil consultar la documentación de Python o buscar ayuda adicional de expertos en Python para comprender los matices de la capacidad de ser llamado y cómo manejarlo correctamente en su código C++.

Comments are closed.