¿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
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 miembrotp_call
o la funciónPyCallable_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()
oPyMethod_Check()
, dependiendo del tipo de objeto esperado. Otra opción es intentar llamar el objeto usandoPyObject_CallObject()
en lugar dePyObject_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++.