2010-12-15 18 views
242

Ruby przykład:Czy istnieje odpowiednik Pythona dla interpolacji ciągów Ruby?

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

Udana Python ciąg konkatenacji jest pozornie gadatliwy do mnie.

+1

Problem jest to, że 'name' jest zmienna lokalna leżący w ciągu, aw Pythonie trzeba wyraźnie zdać słownika lokalny zmienne do formatora napisów, jeśli chcesz, aby z nich korzystać. – katrielalex

+0

To nie był oryginalny problem, ale dzięki. Twój komentarz dał mi trochę lepsze zrozumienie zakresu zmiennego (coś, co wciąż zyskuje na popularności). :) – Caste

+0

Co myślisz o tym? http://stackoverflow.com/questions/16504732/how-could-i-make-my-python-string-interpolation-implementation-work-across-impor – SalchiPapa

Odpowiedz

285

Python 3.6 doda literal string interpolation podobny do interpolacji ciągów Ruby. Począwszy od tej wersji Pythona (która ma zostać wydana pod koniec 2016 r.), Będziesz mógł włączyć wyrażenia w "łańcuchach znaków", np.

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

Przed 3.6, najbliżej można dostać do tego jest

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

Operator % mogą być wykorzystywane do string interpolation w Pythonie. Pierwszy operand jest ciągiem do interpolacji, drugi może mieć różne typy, w tym "mapowanie", odwzorowywanie nazw pól na wartości, które mają być interpolowane. Tutaj użyłem słownika zmiennych lokalnych locals(), aby odwzorować nazwę pola name na jej wartość jako zmienną lokalną.

Ten sam kod metodą ostatnich wersjach Pythona .format() będzie wyglądać następująco:

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

Istnieje również klasa string.Template:

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

@Caste zobacz tutaj: http://docs.python.org/library/stdtypes.html#string-formatowanie i opublikuj komentarz kontrolny, jeśli potrzebujesz więcej szczegółów – mikej

+0

Rozumiem podstawowy jego sens, nie w pełni jednak rozumiem wszystkie dodatkowe symbole i tekst znalezione w przykładzie w dokumentacji. Dlaczego użycie przekonwertować na ciąg tutaj: % (język) s Co oznacza 3 w "03d"? Dlaczego po łańcuchu istnieje% \? Przypisanie zmiennych (jeśli są to w rzeczywistości zmienne) * po * wyrażenie wydruku również mnie wprawia w zakłopotanie. Przepraszam, jeśli to jest ból! – Caste

+1

Dwa podstawowe formaty użyte w tym przykładzie to '% s' dla ciągu znaków i'% 03d' dla numeru wyliczonego na 3 cyfry z wiodącymi zerami. Może to być po prostu napisane 'print"% s ma% 03d "% (" Python ", 2)'. Przykład następnie wykorzystuje umieszczenie klucza odwzorowania w nawiasach po '%', który jest sposobem nadawania symbolom znaczących nazw zamiast polegania na ich kolejności w łańcuchu. Następnie przekazujesz słownik, który odwzorowuje nazwy klawiszy na ich wartości. Dlatego Sven używa funkcji 'locals()', która zwraca dict zawierający wszystkie zmienne lokalne, więc zamapuje 'name' na wartość o nazwie – mikej

20

interpolacja ciąg Pythona jest podobna do printf z C ()

Jeśli spróbujesz:

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

Znacznik %s zostanie zastąpiony zmienną name. Należy spojrzeć tagów funkcji drukowania do: http://docs.python.org/library/functions.html

+1

jak mogę to zrobić za pomocą 2 zmiennych? –

+13

@JulioMarins Użyj krotki: 'print" Pierwszy to% s, drugi to% s "% (var1, var2)'. – refi64

102

Od Python 2.6.x możesz użyć:

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

Należy zauważyć, że operator '%' dla interpolacji napisów jest ** nie ** przestarzały w Pythonie 3.x. http://docs.python.org/dev/py3k/whatsnew/3.0.html#changes-already-present-in-python-2-6 ogłasza plan wycofania '%' zaczynającego się w 3.1, ale to się nigdy nie zdarzyło. –

+7

% -syntax nadal żyje w Pythonie 3 (nie jest przestarzałe od Pythona 3.2) –

+9

Tylko uwaga: liczba w '{}' może zostać wyeliminowana. – 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) 

Zastosowanie:

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 

PS: Wydajność może być problemem. Jest to przydatne w przypadku skryptów lokalnych, a nie dzienników produkcji.

duplikatów:

+0

Druga linia w przykładzie użycia powinna brzmieć 's ('{a}', ** locals())' – Hannes

3

Można również mieć ten

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

Nie wierzę, że OP zamierzała wydrukować '# '. Używają tylko składni Ruby. – jaynp

+0

Masz rację. Zmieniłem odpowiedź. Nie znam Rubiego, więc pomyślałem, że zostanie wydrukowany znak '# '. –

29

Mam opracowany pakiet interpy, że umożliwia interpolację ciąg w Pythonie.

Wystarczy zainstalować przez pip install interpy. A następnie dodaj linię # coding: interpy na początku plików!

Przykład:

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

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

Wydaje się to naprawdę niebezpieczne. – d33tah

+1

preprocessing przez kodowanie, miła sztuczka! – Proton

+0

@ d33tah: Nie, o ile struny są znane podczas kompilacji. –

23

interpolacja String będzie included with Python 3.6 as specified in PEP 498. Będziesz w stanie to zrobić:

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

Uwaga, nienawidzę Spongeboba, więc pisanie tego było trochę bolesne. :)

+0

Thx dla tego odniesienia Spongebob (/ distaste): muszę to teraz przegłosować. – javadba

2

Dla starego Pythona (testowane na 2.4) najlepsze rozwiązanie wskazuje drogę. Można to zrobić:

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() 

I masz

d: 1 f: 1.1 s: s 
Powiązane problemy