Pemformatan string bernama parameter?

135

Saya tahu ini pertanyaan yang sangat sederhana, tetapi saya tidak tahu bagaimana cara meng-google-nya.

bagaimana saya bisa melakukannya

print '<a href="%s">%s</a>' % (my_url)

Jadi itu my_urldigunakan dua kali? Saya berasumsi saya harus "memberi nama" %sdan kemudian menggunakan dict di params, tetapi saya tidak yakin dengan sintaks yang tepat?


FYI saja, saya sadar saya bisa menggunakan my_urldua kali di params, tapi bukan itu intinya :)

mpen
sumber
Judul pertanyaannya agak menyesatkan. Ini tidak ada hubungannya dengan pernyataan print, hanya dengan cara kerja interpolasi string.
Greg Ball
Jika Anda tidak tahu cara mencari di Google, buka di sini untuk menggunakan pencarian: python.org/doc . Ini lebih baik daripada Google karena satu alasan penting.
S. Lotot
@ S.Lott Itu sangat membantu / s
mpen

Jawaban:

81

Di Python 2.6+ dan Python 3, Anda mungkin memilih untuk menggunakan metode pemformatan string yang lebih baru.

print('<a href="{0}">{0}</a>'.format(my_url))

yang menyelamatkan Anda dari pengulangan argumen, atau

print('<a href="{url}">{url}</a>'.format(url=my_url))

jika Anda ingin parameter bernama.

print('<a href="{}">{}</a>'.format(my_url, my_url))

yang benar-benar posisional, dan hanya dilengkapi dengan peringatan bahwa argumen format () mengikuti aturan Python di mana argumen tanpa nama harus didahulukan, diikuti oleh argumen bernama, diikuti oleh * args (urutan seperti list atau tuple) dan kemudian * kwargs (sebuah dict dikunci dengan string jika Anda tahu apa yang baik untuk Anda). Titik interpolasi ditentukan pertama dengan mengganti nilai yang dinamai pada labelnya, dan kemudian posisional dari yang tersisa. Jadi, Anda juga bisa melakukan ini ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, my_url, not_my_url=her_url))

Tapi bukan ini ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, not_my_url=her_url, my_url))
Greg Ball
sumber
Sangat menyenangkan melihat pengaruhnya bergeser dari ++ ke #
cod3monk3y
3
Metode di atas bukan untuk pemformatan string bernama , ini adalah pemformatan string posisi. Jadi ini tidak benar-benar menjawab pertanyaan itu.
jaapz
The "literal {arg1}".format(arg1="arg!")Format bernama bekerja dengan Python 3.5, sedangkan terser yang f"literal {arg1}"merupakan inovasi baru di Python 3.6 atau yang lebih baru, AFAIK.
MarkHu
Komentar dari @jaapz sudah tidak valid mengingat perubahan jawaban ini yang menyertakan sintaks non-posisi print('<a href="{url}">{url}</a>'.format(url=my_url)). Ini bekerja sangat baik dengan Python 2 dan 3.
Danila Vershinin
221
print '<a href="%(url)s">%(url)s</a>' % {'url': my_url}
Ignacio Vazquez-Abrams
sumber
3
Saya lebih suka membuat dikt dengan kwargs:'<a href="%(url)s">%(url)s</a>' % dict(url=my_url)
schlamar
11
Saya bertanya-tanya mengapa Anda lebih suka schmlamar itu? Saya tidak akan langsung tahu apa artinya, dibandingkan dengan deklarasi normal dari
dikt yang
1
The dokumentasi tidak mengatakan kapan ini diperkenalkan, jadi mungkin di semua Python 2 versi.
Evgeni Sergeev
2
Gunakan format () jika Anda bisa, ini berfungsi lebih baik dan di lebih banyak tempat. Gunakan% jika Anda HARUS.
uchuugaka
39

Solusi dengan Python 3.6+

Python 3.6 memperkenalkan pemformatan string literal , sehingga Anda dapat memformat parameter bernama tanpa mengulang salah satu parameter bernama Anda di luar string:

print(f'<a href="{my_url:s}">{my_url:s}</a>')

Ini akan mengevaluasi my_url, jadi jika tidak ditentukan, Anda akan mendapatkan file NameError. Faktanya, alih-alih my_url, Anda dapat menulis ekspresi Python yang berubah-ubah, asalkan dievaluasi ke string (karena :skode pemformatannya). Jika Anda menginginkan representasi string untuk hasil ekspresi yang mungkin bukan string, ganti :sdengan !s, seperti pemformatan string pra-literal biasa.

Untuk detail tentang pemformatan string literal, lihat PEP 498 , di mana ia pertama kali diperkenalkan.

gerrit
sumber
1
PEP itu tampaknya tidak mencakup semua pemformat; Saya pikir mereka sama dengan str.format yang didokumentasikan di sini: docs.python.org/3.4/library/string.html#formatstrings
mpen
6

Anda akan kecanduan sintaks.

Juga C # 6.0, pengembang EcmaScript juga telah memahami sintaks ini.

In [1]: print '{firstname} {lastname}'.format(firstname='Mehmet', lastname='Ağa')
Mehmet Ağa

In [2]: print '{firstname} {lastname}'.format(**dict(firstname='Mehmet', lastname='Ağa'))
Mehmet Ağa
guneysus
sumber
5

Untuk membuat halaman HTML, Anda ingin menggunakan mesin template, bukan interpolasi string sederhana.

Mike Graham
sumber
2
Mesin pembuatan template Django mungkin juga terbukti menjadi alat yang ideal untuk email yang Anda buat.
Mike Graham
6
Apa yang menghentikan Anda dari menggunakan templat Django untuk menghasilkan badan email dengan render()metodenya? Tidak ada yang mengatakan Anda harus memasukkan output template ke HttpResponse(). Django adalah memalukan serbaguna.
Mike DeSimone
1
@ Mike: Saya pikir Django mungkin memiliki solusi untuk ini juga, tetapi saya belum menemukannya: p Saya mungkin akan memindahkan email saya ke dalam templat kalau begitu! Terima kasih. Mungkin saya terlambat, tetapi saya merasa hal itu cukup kaku di beberapa area.
mpen
2
@random orang yang membaca komentar ini: temukan detail lebih lanjut tentang cara melakukannya di sini rossp.org/blog/2006/jul/11/sending-e-mails-templates
mpen
1
Untuk mengomentari pertanyaan, Anda ingin menggunakan komentar, bukan jawaban.
Suriv
2

Selain cara kamus, mungkin berguna untuk mengetahui format berikut:

print '<a href="%s">%s</a>' % (my_url, my_url)

Di sini agak berlebihan, dan cara kamus jelas kurang rentan terhadap kesalahan saat memodifikasi kode, tetapi masih mungkin menggunakan tupel untuk beberapa penyisipan. Yang pertama %smenggantikan elemen pertama dalam tupel, yang kedua %smenggantikan elemen kedua dalam tupel, dan seterusnya untuk setiap elemen dalam tupel.

Ponkadoodle
sumber
Saya baru saja memberi tahu seorang pria karena menyarankan ini :) Dia menghapus postingannya. Saya merasa agak buruk sekarang. Ya, saya sadar saya bisa melakukan ini, tetapi bukan itu yang saya cari. Seperti yang Anda katakan, ini berlebihan, dan my_urlsebenarnya adalah panggilan fungsi yang saya tidak ingin dievaluasi dua kali. Dua kali tidak terlalu buruk, tapi bisa saja dengan mudah 20 kali :)
mpen
5
Saya pikir saya akan menyimpan milik saya, kalau-kalau itu membantu orang lain. Cara kamus sepertinya cara terbaik untuk pergi. Tetapi untuk redundansi, (get_my_url(), )*20hanya memanggil fungsi satu kali, dan menggandakannya 20 kali.
Ponkadoodle
1

Pilihan lainnya adalah menggunakan format_map:

print('<a href="{s}">{s}</a>'.format_map({'s': 'my_url'}))
Danny Varod
sumber