tutorial sirve que programacion para lenguaje español descargar curso caracteristicas python string format python-2.6 built-in

sirve - python tutorial



¿Por qué Python tiene una función de formato y un método de formateo? (2)

Creo que format y str.format hacen cosas diferentes. Aunque podría usar str.format para ambos, tiene sentido tener versiones separadas.

La función de format nivel superior es parte del nuevo "protocolo de formato" que admiten todos los objetos. Simplemente llama al método __format__ del objeto que se pasa, y devuelve una cadena. Esta es una tarea de bajo nivel, y el estilo de Python suele tener funciones integradas para ellos. La respuesta de Paulo Scardine explica algunas de las razones para esto, pero no creo que realmente aborde las diferencias entre qué format y format str.format .

El método str.format es un poco más alto, y también un poco más complejo. No solo puede formatear múltiples objetos en un solo resultado, sino que también puede reordenar, repetir, indexar y hacer otras varias transformaciones en los objetos. No pienses solo en el "{}".format(obj) . str.format está realmente diseñado para más sobre tareas complicadas, como estas:

"{1} {0} {1!r}".format(obj0, obj1) # reorders, repeats, and and calls repr on obj1 "{0.value:.{0.precision}f}".format(obj) # uses attrs of obj for value and format spec "{obj[name]}".format(obj=my_dict) # takes argument by keyword, and does an item lookup

Para el formateo de bajo nivel de cada elemento, str.format basa en la misma maquinaria del protocolo de formato, por lo que puede centrar sus propios esfuerzos en las cosas de nivel superior. Dudo que en realidad llame al format integrado, en lugar de sus argumentos ''métodos __format__ '', pero eso es un detalle de implementación.

Mientras que ("{"+format_code+"}").format(obj) está garantizado para dar los mismos resultados que el format(obj, format_code) , sospecho que este último será un poco más rápido, ya que no necesita analizar el formatee la cadena para verificar si hay algo complicado. Sin embargo, la sobrecarga puede perderse en el ruido en un programa real.

En lo que respecta al uso (incluidos los ejemplos de Stack Overflow), es posible que vea más uso de str.format simple simplemente porque algunos programadores no conocen el format , que es nuevo y bastante oscuro. Por el contrario, es difícil evitar str.format (a menos que haya decidido seguir con el operador % para todo su formateo). Por lo tanto, la facilidad (para usted y sus compañeros programadores) de comprender una llamada str.format puede superar cualquier consideración de rendimiento.

La función de format en builtins parece ser como un subconjunto del método str.format utilizado específicamente para el caso de un formato de un solo objeto.

p.ej.

>>> format(13, ''x'') ''d''

es aparentemente preferido por encima

>>> ''{0:x}''.format(13) ''d''

e IMO se ve mejor, pero ¿por qué no usar str.format en todos los casos para simplificar las cosas? Ambos fueron introducidos en 2.6 así que debe haber una buena razón para tener ambos a la vez, ¿qué es?

Editar: Estaba preguntando sobre el format str.format y no por qué no tenemos un format (13).format


tldr; format simplemente llama obj.__format__ y es usado por el método str.format que hace aún más cosas de nivel superior. Para el nivel inferior, tiene sentido enseñarle a un objeto cómo formatearse.

Es solo azúcar sintáctico

El hecho de que esta función comparta el nombre y la especificación de formato con str.format puede ser engañoso. La existencia de str.format es fácil de explicar: realiza una compleja interpolación de cadenas (reemplazando el antiguo operador % ); format puede formatear un solo objeto como cadena, el subconjunto más pequeño de la especificación str.format . Entonces, ¿por qué necesitamos format ?

La función de format es una alternativa al obj.format(''fmt'') encuentra en algunos lenguajes OO . Esta decisión es coherente con la lógica de len (sobre por qué Python usa una función len(x) lugar de una propiedad x.length como Javascript o Ruby).

Cuando un lenguaje adopta el obj.format(''fmt'') (u obj.length , obj.length , etc.), se impide que las clases tengan un atributo llamado format (o length , toString , se entiende la idea); de lo contrario sombrearía el método estándar del lenguaje. En este caso, los diseñadores del lenguaje están cargando la tarea de evitar los conflictos de nombres en el programador.

Python es muy aficionado al PoLA y adoptó la __dunder__ (doble guión bajo) para __dunder__ con el fin de minimizar la posibilidad de conflictos entre los atributos definidos por el usuario y el lenguaje incorporado. Así que obj.format(''fmt'') convierte en obj.__format__(''fmt'') , y por supuesto puede llamar obj.__format__(''fmt'') lugar de format(obj, ''fmt'') (de la misma manera que puede llamar obj.__len__() lugar de len(obj) ).

Usando tu ejemplo:

>>> ''{0:x}''.format(13) ''d'' >>> (13).__format__(''x'') ''d'' >>> format(13, ''x'') ''d''

¿Cuál es más limpio y más fácil de escribir? El diseño de Python es muy pragmático, no solo es más limpio, sino que está bien alineado con el enfoque de Python basado en duck-typed para OO y brinda libertad a los diseñadores de lenguaje para cambiar / extender la implementación subyacente sin romper el código heredado.

El PEP 3101 introdujo el nuevo método str.format y el format incorporado sin ningún comentario sobre la razón de ser de la función de format , pero la implementación es obviamente solo azúcar sintáctica :

def format(value, format_spec): return value.__format__(format_spec)

Y aquí descanso mi caso.

¿Qué dijo Guido al respecto (o es oficial?)

Citando el mismo BDFL sobre len :

Antes que nada, elegí len(x) sobre x.len() para razones de HCI ( def __len__() llegó mucho más tarde). En realidad, hay dos razones entrelazadas, ambas HCI :

(a) Para algunas operaciones, la notación de prefijo simplemente lee mejor que postfix - las operaciones de prefijo (¡e infijo!) tienen una larga tradición en matemáticas a las que les gustan las notaciones donde los elementos visuales ayudan al matemático a pensar en un problema. Compare lo fácil con lo que reescribimos una fórmula como x*(a+b) en x*a + x*b a la torpeza de hacer lo mismo usando una notación OO cruda.

(b) Cuando leo un código que dice len(x) sé que está pidiendo la longitud de algo. Esto me dice dos cosas: el resultado es un número entero, y el argumento es algún tipo de contenedor. Por el contrario, cuando leo x.len() , tengo que saber que x es un tipo de contenedor que implementa una interfaz o hereda de una clase que tiene un len() estándar. Sea testigo de la confusión que ocasionalmente tenemos cuando una clase que no implementa una asignación tiene un método get() o keys() , o algo que no es un archivo tiene un método write() .

Al decir lo mismo de otra manera, veo '' len '' como una operación incorporada. Odiaría perder eso. / ... /

fuente: [email protected] (la publicación original here también tiene la pregunta original que respondía Guido). Abarnert sugiere también:

Hay un razonamiento adicional sobre len en las preguntas frecuentes sobre diseño e historia . Aunque no es tan completa ni tan buena como una respuesta, es indiscutiblemente oficial. - Abarnert

¿Es esto una preocupación práctica o simplemente una sintaxis nimia?

Esta es una preocupación muy práctica y real en idiomas como Python, Ruby o Javascript porque en los lenguajes de tipado dinámico cualquier objeto mutable es efectivamente un espacio de nombres, y el concepto de métodos o atributos privados es una cuestión de convención. Posiblemente no podría decirlo mejor que Abarnert en su comentario:

Además, en lo que respecta al problema de contaminación del espacio de nombres con Ruby y JS, vale la pena señalar que este es un problema inherente a los lenguajes de tipo dinámico. En los lenguajes de tipo estático tan diversos como Haskell y C ++, las funciones gratuitas específicas de tipo no solo son posibles, sino también idiomáticas. (Consulte el Principio de la interfaz .) Pero en los lenguajes de tipado dinámico como Ruby, JS y Python, las funciones gratuitas deben ser universales. Una gran parte del diseño del lenguaje / biblioteca para lenguajes dinámicos es elegir el conjunto correcto de tales funciones.

Por ejemplo, acabo de dejar Ember.js a favor de Angular.js porque estaba cansado de los conflictos de espacio de nombre en Ember ; Angular maneja esto usando una estrategia elegante similar a Python de prefijación de métodos incorporados (con $thing en Angular, en lugar de guiones bajos como python), para que no entren en conflicto con los métodos y propiedades definidos por el usuario. Sí, todo __thing__ no es particularmente bonito, pero me alegro de que Python tomó este enfoque porque es muy explícito y evita la clase de errores PoLA respecto a los conflictos de espacio de nombres de objetos.