Impresión de valores booleanos Verdadero/Falso con el método format() en Python
python-2.7 string-formatting (1)
Excelente pregunta! Creo que tengo la respuesta. Esto requiere excavar a través del código fuente de Python en C, así que ten paciencia.
Primero, el format(obj, format_spec)
es solo azúcar sintáctica para obj.__format__(format_spec)
. Específicamente donde ocurre esto, tendrías que buscar en abstract.c , en la función:
PyObject *
PyObject_Format(PyObject* obj, PyObject *format_spec)
{
PyObject *empty = NULL;
PyObject *result = NULL;
...
if (PyInstance_Check(obj)) {
/* We''re an instance of a classic class */
HERE -> PyObject *bound_method = PyObject_GetAttrString(obj, "__format__");
if (bound_method != NULL) {
result = PyObject_CallFunctionObjArgs(bound_method,
format_spec,
NULL);
...
}
Para encontrar la llamada exacta, tenemos que buscar en intobject.c :
static PyObject *
int__format__(PyObject *self, PyObject *args)
{
PyObject *format_spec;
...
return _PyInt_FormatAdvanced(self,
^ PyBytes_AS_STRING(format_spec),
| PyBytes_GET_SIZE(format_spec));
LET''S FIND THIS
...
}
_PyInt_FormatAdvanced
realidad se define como una macro en formatter_string.c como una función que se encuentra en formatter.h :
static PyObject*
format_int_or_long(PyObject* obj,
STRINGLIB_CHAR *format_spec,
Py_ssize_t format_spec_len,
IntOrLongToString tostring)
{
PyObject *result = NULL;
PyObject *tmp = NULL;
InternalFormatSpec format;
/* check for the special case of zero length format spec, make
it equivalent to str(obj) */
if (format_spec_len == 0) {
result = STRINGLIB_TOSTR(obj); <- EXPLICIT CAST ALERT!
goto done;
}
... // Otherwise, format the object as if it were an integer
}
Y ahí está tu respuesta. Una simple comprobación de si format_spec_len
es 0
, y si lo es, convierte obj
en una cadena. Como usted bien sabe, str(True)
es ''True''
, ¡y el misterio ha terminado!
Estaba tratando de imprimir una tabla de verdad para expresiones booleanas. Mientras hacía esto, me topé con lo siguiente:
>>> format(True, "") # shows True in a string representation, same as str(True)
''True''
>>> format(True, "^") # centers True in the middle of the output string
''1''
Tan pronto como especifique un especificador de formato, format()
convierte True
en 1
. Sé que bool
es una subclase de int
, por lo que True
evalúa como 1
:
>>> format(True, "d") # shows True in a decimal format
''1''
Pero, ¿por qué usar el especificador de formato cambia ''True''
a 1
en el primer ejemplo?
Me dirigí a los documentos para su aclaración . Lo único que dice es:
Una convención general es que una cadena de formato vacía (
""
) produce el mismo resultado que si hubiera llamado astr()
en el valor. Una cadena de formato no vacía normalmente modifica el resultado.
Así que la cadena se modifica cuando usas un especificador de formato. Pero ¿por qué el cambio de True
a 1
si solo se especifica un operador de alineación (por ejemplo, ^
)?