Ruby'nin string enterpolasyonuna eşdeğer bir Python var mı?


343

Ruby örneği:

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

Başarılı Python dizesi birleştirme bana görünüşte ayrıntılı.


2
Buradaki sorun namedizede yatan yerel bir değişken ve Python'da bunları kullanmak istiyorsanız, yerel değişkenlerin sözlüğünü açıkça dize biçimlendiricisine iletmeniz gerekiyor.
Katriel

Bu asıl sorun değildi, ama teşekkürler. Yorumunuz değişken kapsamı biraz daha iyi anlamamı sağladı (hala katlandığım bir şey). :)
Kast

1
Öyleyse bunun hakkında ne düşünüyorsun? stackoverflow.com/questions/16504732/…
SalchiPapa


Yanıtlar:


413

Python 3.6, Ruby'nin dize enterpolasyonuna benzer değişmez dize enterpolasyonu ekleyecektir . Python'un (2016'nın sonunda yayınlanması planlanan) bu sürümünden başlayarak, ifadeleri "f-dizeleri" ne ekleyebileceksiniz, örn.

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

3.6'dan önce, buna en yakın olan

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

%Operatör için kullanılabilecek dize enterpolasyon Python. İlk işlenen enterpolasyon yapılacak dizedir, ikincisi ise "eşleme", alan adlarının enterpole edilecek değerlerle eşlenmesi de dahil olmak üzere farklı türlere sahip olabilir. Burada yerel değişkenlerin sözlüğünü kullandımlocals() alan adını nameyerel bir değişken olarak değerine eşlemek için .

En .format()son Python sürümlerinin yöntemini kullanan aynı kod şöyle görünecektir:

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

Ayrıca string.Templatesınıf var:

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

@Caste buraya bakın: docs.python.org/library/stdtypes.html#string-formatting ve daha fazla ayrıntıya ihtiyacınız varsa bir takip yorumu gönderin
mikej

Bunun temel nedenini anlıyorum, ancak belgelerdeki örnekte bulunan tüm ek sembolleri ve metni tam olarak anlamıyorum. Neden dizeye dönüştürmek kullanıldığında:% (dil) s '03d' içindeki 3 ne anlama geliyor? Neden dizeden sonra% \ var? Yazdırma ifadesinden sonra değişkenlerin atanması (aslında değişkenler ise) beni de karıştırır. Bu bir acıysa özür dilerim!
Caste

1
Örnekte kullanılan iki temel biçim %s, bir dize ve %03dbaştaki sıfırlarla 3 basamağa kadar doldurulmuş bir sayı içindir. Sadece yazılabilirdi print "%s has %03d" % ("Python", 2). Örnek daha sonra parantez içine bir eşleme anahtarı koymaktan yararlanır; bundan sonra %yer tutuculara dizedeki sıralarına güvenmek yerine anlamlı adlar vermenin bir yolu vardır. Daha sonra anahtar adlarını değerleriyle eşleştiren bir sözlük iletirsiniz. Bu yüzden Sven, locals()tüm yerel değişkenlerinizi içeren bir diksiyon döndüren işlevi kullanıyor, böylece namead değerine
eşleşecek

Bir dönüşüm türünün gerekli kullanımı beni ilk şaşırtan şeydi. Yani, dokümantasyon terminolojisini kullanarak. % Belirteci başlatır. (Dil) için bir dönüşüm bayrağı yoktur, yalnızca bir dönüşüm türü (sondaki 's'); (sayı) ise, sırasıyla '0' (ve '3') olan bir (veya iki) dönüşüm işaretine sahiptir. 'D' dönüşüm türüdür ve bir tamsayı olduğunu belirtir. Doğru anladım mı?
Kast

@Caste: Evet, bu doğru. A'yı her zaman sdönüşüm türü olarak kullanabileceğinizi unutmayın - Python hemen hemen her şeyi bir dizeye dönüştürebilir. Ancak elbette diğer dönüşüm türlerinin özel biçimlendirme özelliklerini kaybedersiniz.
Sven Marnach

143

Python 2.6.X sürümünden bu yana kullanmak isteyebilirsiniz:

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

27
O Not %dize enterpolasyon için operatör olduğu değil Python 3.x kaldırılmış docs.python.org/dev/py3k/whatsnew/… 3.1'den% başlayarak kullanımdan kaldırılma planını açıkladı , ancak bu asla olmadı.
Sven Marnach

8
% -syntax hala Python 3'te yaşıyor (Python 3.2'den itibaren kullanımdan kaldırılmamış)
Corey Goldberg

9
Sadece bir not: İçindeki sayı {}ortadan kaldırılabilir.
çizmek

32

Python'da dize enterpolasyonunu sağlayan interpy paketini geliştirdim .

Sadece üzerinden yükleyin pip install interpy. Ve sonra, satırı ekleyin# coding: interpy dosyalarınızın başına ekleyin!

Misal:

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

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

3
Bu gerçekten güvensiz görünüyor.
d33tah

@ d33tah: Hayır, dizeler derleme zamanında bilindiği sürece.
Clément

28

Python'un dize enterpolasyonu C'nin printf () işlevine benzer

Eğer denersen:

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

Etiketi değişkenle %sdeğiştirilir name. Yazdırma işlevi etiketlerine bir göz atmalısınız: http://docs.python.org/library/functions.html


1
2 değişken ile bu şekilde nasıl yapabilirim?
Julio Marins

16
@JulioMarins bir demet kullanın: print "First is %s, second is %s" % (var1, var2).
kirbyfan64sos

28

Dize enterpolasyonu, PEP 498'de belirtildiği gibi Python 3.6'ya dahil edilecektir . Bunu yapabileceksiniz:

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

Sünger Bob'dan nefret ettiğimi unutmayın, bu yüzden bunu yazmak biraz acı vericiydi. :)


Bu Spongebob referansı için teşekkürler (/ distaste): şimdi bunu yükseltmeliyim.
javadba

4

Buna da sahip olabilirsiniz

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


OP'nin #yazdırılmayı amaçladığına inanmıyorum . Sadece Ruby sözdizimini kullanıyorlar.
jaynp

Haklısın. Cevabı düzenledim. Ruby'ye aşina değilim, bu yüzden #karakterin basılacağını düşündüm .
Quan To

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)

Kullanımı:

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

Not: performans bir sorun olabilir. Bu, üretim günlükleri için değil, yerel komut dosyaları için kullanışlıdır.

Yinelendi:


2

Eski Python (2.4'te test edildi) için en iyi çözüm yolu gösteriyor. Bunu yapabilirsiniz:

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

Ve sen al

d: 1 f: 1.1 s: s

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.