español - ¿Cuál es la forma “correcta” de pasar un booleano a una extensión de Python C?
python c++ (3)
4 tal vez haya una forma de obtener cualquier tipo de variable y obtener su valor de verdad (es decir, una matriz vacía es falsa, etc.) que es la función de python que normalmente hace.
Sí: (de la referencia de la API de Python / C )
int PyObject_IsTrue(PyObject *o)
Devuelve 1 si el objeto o se considera verdadero, y 0 en caso contrario. Esto es equivalente a la expresión de Python no o no. En caso de fallo, devuelve -1.
EDITAR. Para responder a la pregunta real, creo que el enfoque 1 es correcto, porque int realmente es el tipo correspondiente en C. El enfoque 4 es bueno, pero si documenta su función como tomar un bool, no está obligado a aceptar cualquier objeto. Las comprobaciones de tipo explícitas como en 3 sin motivo están mal vistas en Python. La conversión a otro objeto de Python como en 2 no ayuda a su código C.
Este es un ejemplo simple de la documentación de Python (http://docs.python.org/extending/extending.html):
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}
Si quiero pasar un parámetro booleano adicional a la función, ¿cuál es la forma "correcta" de hacerlo?
No parece haber una opción de bool para pasar a PyArg_ParseTuple (). Así que pensé en lo siguiente:
- lee un entero y solo usa el valor (ya que bool es una subclase de int)
- llamar a PyBool_FromLong () en un entero
- lee y opone y llama a PyBool_Check () para verificar que es un bool
- tal vez haya una manera de obtener cualquier tipo de variable y obtener su valor de verdad (es decir, una matriz vacía es falsa, etc.) que es la función de python que normalmente hace.
¿Alguno de estos preferible? ¿Otras opciones?
Actualmente, el análisis de un entero (como "i"
) es la forma aceptada de tomar un bool.
Desde Python 3.3, PyArg_ParseTuple
aceptará "p"
(para "predicado"), según las últimas NOTICIAS :
- Problema nº 14705 : la familia de funciones PyArg_Parse () ahora admite la unidad de formato ''p'', que acepta un argumento de "predicado booleano". Convierte cualquier valor de Python en un entero - 0 si es "falso", y 1 de lo contrario.
Tenga en cuenta que cuando se usa PyArg_ParseTuple
con "p"
, el argumento debe ser un (puntero a) int
, no el tipo bool
C99:
int x; // not "bool x"
PyArg_ParseTuple(args, kwds, "p", &x);
He encontrado otro enfoque:
PyObject* py_expectArgs;
bool expectArgs;
PyArg_ParseTupleAndKeywords(args, keywds, (char *)"O!", (char **)kwlist, &PyBool_Type, &py_expectArgs);
expectArgs = PyObject_IsTrue(py_expectArgs);
En caso de una llamada param incorrecta, el argumento "auto" excepción "1 debe ser bool, no int"