Apakah ada Python yang setara dengan interpolasi string Ruby?

343

Contoh Ruby:

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

Rangkaian string Python yang berhasil tampaknya cocok untuk saya.

Kasta
sumber
2
Masalahnya di sini adalah bahwa itu nameadalah variabel lokal yang terletak di string, dan dengan Python Anda harus secara eksplisit meneruskan kamus variabel lokal ke pemformat string jika Anda ingin menggunakannya.
Katriel
Ini bukan masalah asli, tapi terima kasih. Komentar Anda memberi saya sedikit pemahaman yang lebih baik tentang ruang lingkup variabel (sesuatu yang saya masih mendapatkan dasar). :)
Caste
1
Bagaimana menurut Anda tentang yang ini? stackoverflow.com/questions/16504732/…
SalchiPapa
2
Lihat stackoverflow.com/a/33264516/55721 untuk fitur persis ini di 3.6
dss539

Jawaban:

413

Python 3.6 akan menambahkan interpolasi string literal mirip dengan interpolasi string Ruby. Dimulai dengan versi Python (yang dijadwalkan akan dirilis pada akhir 2016), Anda akan dapat memasukkan ekspresi dalam "f-string", misalnya

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

Sebelum ke 3.6, yang terdekat yang bisa Anda dapatkan adalah

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

The %operator dapat digunakan untuk interpolasi string di Python. Operan pertama adalah string yang akan diinterpolasi, yang kedua dapat memiliki tipe yang berbeda termasuk "pemetaan", memetakan nama bidang dengan nilai yang akan diinterpolasi. Di sini saya menggunakan kamus variabel lokallocals() untuk memetakan nama bidang nameke nilainya sebagai variabel lokal.

Kode yang sama menggunakan .format()metode versi Python terbaru akan terlihat seperti ini:

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

Ada juga string.Templatekelasnya:

tmpl = string.Template("Who lives in a Pineapple under the sea? $name.")
print(tmpl.substitute(name="Spongebob Squarepants"))
Sven Marnach
sumber
@Caste lihat di sini: docs.python.org/library/stdtypes.html#string-formatting dan poskan komentar tindak lanjut jika Anda memerlukan rincian lebih lanjut
mikej
Saya mengerti intinya, saya tidak sepenuhnya memahami semua simbol dan teks tambahan yang ditemukan dalam contoh di dokumentasi. Mengapa penggunaan convert to string di sini:% (bahasa) s Apa arti dari 3 dalam '03d'? Mengapa setelah string ada% \? Penugasan variabel (jika mereka sebenarnya variabel) setelah ekspresi cetak membingungkan saya juga. Maaf jika ini menyebalkan!
Kasta
1
Dua format dasar yang digunakan dalam contoh adalah %suntuk string dan %03duntuk angka yang diisi hingga 3 digit dengan nol nol di depannya. Bisa saja ditulis print "%s has %03d" % ("Python", 2). Contoh tersebut kemudian menggunakan menempatkan kunci pemetaan dalam tanda kurung setelah %yang merupakan cara untuk memberi nama penampung yang berarti daripada mengandalkan pesanan mereka dalam string. Anda kemudian melewati kamus yang memetakan nama-nama kunci dengan nilainya. Itu sebabnya Sven menggunakan locals()fungsi yang mengembalikan dict yang berisi semua variabel lokal Anda sehingga akan memetakan nameke nilai nama
mikej
Penggunaan jenis konversi yang diperlukan adalah yang pertama membingungkan saya. Jadi, gunakan terminologi dokumentasi. % Memulai specifier. Tidak ada flag konversi untuk (bahasa), hanya tipe konversi (trailing 's'); (angka) namun memiliki satu (atau dua) bendera konversi yang masing-masing '0' (dan '3'). 'D' adalah tipe konversi dan menandakan itu adalah bilangan bulat. Apakah saya mengerti dengan benar?
Kasta
@ Cook: Ya, itu pada dasarnya benar. Perhatikan bahwa Anda selalu dapat menggunakan ssebagai tipe konversi - Python dapat mengonversi apa saja menjadi string. Tetapi tentu saja Anda akan kehilangan kemampuan format khusus dari jenis konversi lainnya.
Sven Marnach
143

Karena Python 2.6.X Anda mungkin ingin menggunakan:

"my {0} string: {1}".format("cool", "Hello there!")
EinLama
sumber
27
Perhatikan bahwa %operator untuk interpolasi string tidak ditinggalkan dalam Python 3.x. docs.python.org/dev/py3k/whatsnew/… mengumumkan rencana untuk mundur% mulai dari 3.1, tetapi ini tidak pernah terjadi.
Sven Marnach
8
% -syntax masih hidup di Python 3 (tidak ditinggalkan pada Python 3.2)
Corey Goldberg
9
Hanya sebuah catatan: angka di {}dapat saya hilangkan.
gambar
32

Saya telah mengembangkan paket interpy , yang memungkinkan interpolasi string dengan Python .

Instal saja via pip install interpy. Dan kemudian, tambahkan baris # coding: interpydi awal file Anda!

Contoh:

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

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n#{name}."
Syrus Akbary Nieto
sumber
3
Ini sepertinya sangat tidak aman.
d33tah
@ d33tah: Tidak, selama string diketahui pada waktu kompilasi.
Clément
28

Interpolasi string Python mirip dengan printf C ()

Jika kamu mencoba:

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

Tag %sakan diganti dengan namevariabel. Anda harus melihat ke tag fungsi cetak: http://docs.python.org/library/functions.html

Oleiade
sumber
1
bagaimana saya bisa melakukan ini dengan 2 variabel?
Julio Marins
16
@JulioMarins Gunakan tupel: print "First is %s, second is %s" % (var1, var2).
kirbyfan64sos
28

Interpolasi string akan dimasukkan dengan Python 3.6 sebagaimana ditentukan dalam PEP 498 . Anda akan dapat melakukan ini:

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

Perhatikan bahwa saya membenci Spongebob, jadi menulis ini sedikit menyakitkan. :)

kirbyfan64sos
sumber
Thx untuk referensi Spongebob (/ jijik): harus membenarkan ini sekarang.
javadba
4

Anda juga dapat memiliki ini

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

Quan To
sumber
Saya tidak percaya OP ingin #dicetak. Mereka hanya menggunakan sintaksis Ruby.
jaynp
Kamu benar. Saya mengedit jawabannya. Saya tidak terbiasa dengan Ruby, jadi saya pikir #karakternya akan dicetak.
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)

Pemakaian:

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: kinerja bisa jadi masalah. Ini berguna untuk skrip lokal, bukan untuk log produksi.

Duplikat:

Paulo Check
sumber
2

Untuk Python lama (diuji pada 2.4) solusi teratas menunjukkan jalannya. Kamu bisa melakukan ini:

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

Dan kamu mengerti

d: 1 f: 1.1 s: s
Michael Fox
sumber