funcion - python separar string por caracter
Usando! S vs.: s para formatear una cadena en Python (3)
De la documentación, formato de cadena de Python :
El field_name es seguido opcionalmente por un campo de conversión, que está precedido por un signo de exclamación ''!'', Y un formato_espec, que está precedido por dos puntos '':''.
Entonces no, no es lo mismo.
Por ejemplo:
Si desea imprimir un flotador como una cadena, necesita una conversión (float → string).
"{!s}".format(2.1457)
>>> 2.1457
type("{!s}".format(2.1457))
>>> <type ''str''>
Si no usa la marca de conversión, obtendrá un error.
"{:s}".format(2.1457)
>>> ValueError: Unknown format code ''s'' for object of type ''float''
Tengo mucha curiosidad sobre :s
cadena de formato :s
en Python 3. La documentación dice que !s
es la conversión y que :s
es format_spec
.
También dice que !s
aplicará str()
, pero no dice nada similar sobre :s
. Creo que no hay una diferencia significativa entre ellos, pero quiero estar seguro. ¿Alguien puede aclarar esto?
Algunos ejemplos de código:
print("{!s}".format("this"))
print("{:s}".format("that"))
# I want to be sure that these two are processed identically internally
Todavía es confuso, pero permítanme concluir con mis propias palabras (laico).
-
type("whatever".format)
siempre esstr
. - Use
!s
si desea convertir el objeto enstr
antes de formatear. -
:s
significa que el objeto (o el objeto convertido) se tratará comostr
durante algún proceso de formateo interno. Es elformat_spec
predeterminado.
¿Hay algo mal aquí?
Tienes mala suerte de que uses cadenas como el valor para formatear. Usando casi cualquier otro objeto obtendrías cómo estos no son lo mismo.
En términos de laico (en la medida de lo posible):
- La ausencia o existencia de la bandera de conversión especifica el tipo del valor que vamos a formatear y, por extensión, quién es
__format__
le llamaremos. Como señala Martjin, al usar esto podemos evitar ciertos comportamientos y tratar el valor de manera más genérica (como una cadena). Viene en tres sabores diferentes que corresponden a las tres formas diferentes en que un objeto puede elegir representarse a sí mismo como una cadena. - El especificador de tipo, junto con otros especificadores, especifica cómo se debe presentar finalmente el tipo que tenemos . Para cadenas no hay un conjunto completo de opciones (una cadena se presenta como está) pero, para tipos como
int
s, puede tener diferentes presentaciones.
Creo, sin embargo, que ese type
es probablemente un nombre confuso para dar este especificador.
!s
, y sus hermanos !a
y !r
aplican str()
, ascii()
y repr()
respectivamente antes de la interpolación y el formateo. Estos se denominan indicadores de conversión y forman parte de la especificación de la Sintaxis de cadena de formato , no de la especificación de formato por campo aplicada a los valores al interpolar:
El campo de conversión provoca una coerción de tipo antes de formatear . Normalmente, el trabajo de formatear un valor se realiza mediante el
__format__()
del valor en sí. Sin embargo, en algunos casos es deseable forzar a un tipo a formatearlo como una cadena, anulando su propia definición de formateo. Al convertir el valor en una cadena antes de llamar a__format__()
, se omite la lógica de formateo normal.
Negrita énfasis mío.
:s
solo se aplica después al resultado de la conversión (o al objeto original si no se ha aplicado ninguna conversión), y solo si el método __format__
para el tipo de objeto admite esa opción de formato. Por lo general, solo los objetos de tipo str
admiten este formateador; está allí como predeterminado, principalmente porque el mini idioma de especificación de formato permite la existencia de un carácter de tipo y porque el formato de estilo %
printf
tenía un formato %s
. Si intentas aplicar el tipo s
a un objeto que no lo admite, obtendrías una excepción.
Use !s
(o !a
!r
) cuando tenga un objeto que no sea en sí mismo una cadena y no admita el formateo de otra manera (no todos los tipos lo hacen) o formateará de forma diferente a su str()
, ascii()
o conversiones de repr()
:
>>> class Foo:
... def __str__(self):
... return "Foo as a string"
... def __repr__(self):
... return "<Foo as repr, with åéæ some non-ASCII>"
... def __format__(self, spec):
... return "Foo formatted to {!r} spec".format(spec)
...
>>> print("""/
... Different conversions applied:
... !s: {0!s:>60s}
... !r: {0!r:>60s}
... !a: {0!a:>60s}
... No conversions: {0:>50s}
... """.format(Foo()))
Different conversions applied:
!s: Foo as a string
!r: <Foo as repr, with åéæ some non-ASCII>
!a: <Foo as repr, with /xe5/xe9/xe6 some non-ASCII>
No conversions: Foo formatted to ''>50s'' spec
Nota: todos los formatos especificados por las especificaciones de formato son responsabilidad del método __format__
; la última línea no aplica la operación de alineación en la especificación de formato >50s
, el método Foo.__format__
solo lo usó como texto literal en una operación de formateo (usando una conversión !r
aquí).
Para los valores convertidos, por otro lado, se usa el método str.__format__
y la salida se alinea a la derecha en un campo de 50 caracteres de ancho, rellenado con espacios a la izquierda.