2010-12-15 15 views
242

ejemplo Ruby:¿Hay un Python equivalente a la interpolación de cadenas de Ruby?

name = "Spongebob Squarepants" 
puts "Who lives in a Pineapple under the sea? \n#{name}." 

El éxito de la concatenación de cadenas de Python es en apariencia prolija a mí.

+1

El problema aquí es que 'name' es una variable local tumbado en la cadena, y en Python que tiene que pasar explícitamente el diccionario de locales variables al formateador de cadenas si desea que las use. – katrielalex

+0

Este no era el problema original, pero gracias. Tu comentario me dio un poco mejor entendimiento del alcance variable (algo con lo que todavía estoy ganando terreno). :) – Caste

+0

¿Qué piensas de este, entonces? http://stackoverflow.com/questions/16504732/how-could-i-make-my-python-string-interpolation-implementation-work-across-impor – SalchiPapa

Respuesta

285

Python 3.6 agregará literal string interpolation similar a la interpolación de cadenas de Ruby. A partir de esa versión de Python (que está programada para finales de 2016), podrá incluir expresiones en "f-strings", p.

name = "Spongebob Squarepants" 
print(f"Who lives in a Pineapple under the sea? {name}.") 

Antes de 3,6, lo más cerca que puede llegar a esto es

name = "Spongebob Squarepants" 
print("Who lives in a Pineapple under the sea? %(name)s." % locals()) 

El operador % se puede utilizar para string interpolation en Python. El primer operando es la cadena que se va a interpolar, el segundo puede tener diferentes tipos, incluido un "mapeo", asignando nombres de campo a los valores que se van a interpolar. Aquí utilicé el diccionario de variables locales locals() para asignar el nombre de campo name a su valor como una variable local.

El mismo código utilizando el método de las últimas versiones de Python .format() se vería así:

name = "Spongebob Squarepants" 
print("Who lives in a Pineapple under the sea? {name!s}.".format(**locals())) 

También existe la clase string.Template:

tmpl = string.Template("Who lives in a Pineapple under the sea? $name.") 
print(tmpl.substitute(name="Spongebob Squarepants")) 
+0

@Caste vea aquí: http://docs.python.org/library/stdtypes.html#string-formatting y publique un comentario de seguimiento si necesita más detalles – mikej

+0

Entiendo su esencia básica, no entiendo completamente todos los símbolos adicionales y el texto encontrado en el ejemplo en la documentación. Por qué el uso de convertir a cadena aquí: % (idioma) s ¿Qué significa 3 en '03d'? ¿Por qué después de la cadena hay% \? La asignación de variables (si de hecho son variables) * después de * la expresión de impresión también me confunde. Lo siento si esto es un dolor! – Caste

+1

Los dos formatos básicos utilizados en el ejemplo son '% s' para una cadena y'% 03d' para un número rellenado a 3 dígitos con ceros a la izquierda. Podría simplemente escribirse 'print"% s tiene% 03d "% (" Python ", 2)'. El ejemplo luego utiliza la colocación de una clave de mapeo entre corchetes después del '%', que es una forma de dar a los marcadores de posición nombres significativos en lugar de confiar en su orden en la cadena. A continuación, pasa un diccionario que asigna los nombres de las claves a sus valores. Es por eso que Sven está usando la función 'locals()' que devuelve un dict que contiene todas sus variables locales, por lo que asignará 'nombre' al valor de nombre – mikej

20

interpolación de cadenas de Python es similar a printf de C ()

Si prueba:

name = "SpongeBob Squarepants" 
print "Who lives in a Pineapple under the sea? %s" % name 

La etiqueta %s se reemplazará con la variable name. Usted debe echar un vistazo a las etiquetas de la función de impresión: http://docs.python.org/library/functions.html

+1

¿cómo puedo hacer esto con 2 variables? –

+13

@JulioMarins Usa una tupla: 'print" Primero es% s, el segundo es% s "% (var1, var2)'. – refi64

102

Como Python 2.6.X es posible que desee usar:

"my {0} string: {1}".format("cool", "Hello there!") 
+20

Tenga en cuenta que el operador '%' para la interpolación de cadenas está ** no ** en desuso en Python 3.x. http://docs.python.org/dev/py3k/whatsnew/3.0.html#changes-already-present-in-python-2-6 anuncia el plan para depreciar '%' comenzando en 3.1, pero esto nunca sucedió. –

+7

% -syntax aún vive en Python 3 (no obsoleto a partir de Python 3.2) –

+9

Solo una nota: el número en '{}' me puede eliminar. – draw

3
import inspect 
def s(template, **kwargs): 
    "Usage: s(string, **locals())" 
    if not kwargs: 
     frame = inspect.currentframe() 
     try: 
      kwargs = frame.f_back.f_locals 
     finally: 
      del frame 
     if not kwargs: 
      kwargs = globals() 
    return template.format(**kwargs) 

Uso:

a = 123 
s('{a}', locals()) # print '123' 
s('{a}') # it is equal to the above statement: print '123' 
s('{b}') # raise an KeyError: b variable not found 

PD: el rendimiento puede ser un problema Esto es útil para scripts locales, no para registros de producción.

duplicados:

+0

La segunda línea en el ejemplo de uso debe leer 's ('{a}', ** locals())' – Hannes

3

También puede tener este

name = "Spongebob Squarepants" 
print "Who lives in a Pineapple under the sea? \n{name}.".format(name=name) 

http://docs.python.org/2/library/string.html#formatstrings

+0

No creo que OP haya intentado imprimir el '#'. Solo están usando la sintaxis de Ruby. – jaynp

+0

Tienes razón. Edité la respuesta. No estoy familiarizado con Ruby, así que pensé que el carácter '#' se imprimiría. –

29

he desarrollado el paquete interpy, que permite la interpolación de cadenas en Python.

Simplemente instálelo a través de pip install interpy. Y luego, agregue la línea # coding: interpy al comienzo de sus archivos.

Ejemplo:

#!/usr/bin/env python 
# coding: interpy 

name = "Spongebob Squarepants" 
print "Who lives in a Pineapple under the sea? \n#{name}." 
+2

Esto parece realmente inseguro. – d33tah

+1

preprocesamiento por codificación, buen truco! – Proton

+0

@ d33tah: No, siempre que las cadenas se conozcan en tiempo de compilación. –

23

interpolación de cadenas va a ser included with Python 3.6 as specified in PEP 498. Usted podrá hacer esto:

name = 'Spongebob Squarepants' 
print(f'Who lives in a Pineapple under the sea? \n{name}') 

Tenga en cuenta que odio a Bob Esponja, por lo que escribir esto fue un poco doloroso. :)

+0

Thx para esa referencia de Spongebob (/ distaste): tengo que votar esto ahora. – javadba

2

Para el viejo Python (probado en 2.4) la mejor solución indica el camino. Usted puede hacer esto:

import string 

def try_interp(): 
    d = 1 
    f = 1.1 
    s = "s" 
    print string.Template("d: $d f: $f s: $s").substitute(**locals()) 

try_interp() 

y se obtiene

d: 1 f: 1.1 s: s 
Cuestiones relacionadas