python python-2.7 boolean string-formatting string.format

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 a str() 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, ^ )?