Menggunakan beberapa argumen untuk pemformatan string dalam Python (mis., '% S ...% s')

174

Saya memiliki string yang mirip '%s in %s'dan saya ingin tahu cara memisahkan argumen sehingga keduanya adalah% s yang berbeda. Pikiranku datang dari Jawa datang dengan ini:

'%s in %s' % unicode(self.author),  unicode(self.publication)

Tapi ini tidak berfungsi, jadi bagaimana tampilannya di Python?

Dekan
sumber

Jawaban:

191

Jawaban Mark Cidade benar - Anda harus menyediakan tuple.

Namun dari Python 2.6 dan seterusnya Anda dapat menggunakan formatsebagai ganti %:

'{0} in {1}'.format(unicode(self.author,'utf-8'),  unicode(self.publication,'utf-8'))

Penggunaan %untuk memformat string tidak lagi dianjurkan.

Metode pemformatan string ini adalah standar baru dalam Python 3.0, dan harus lebih disukai daripada pemformatan% yang dijelaskan dalam Operasi Pemformatan String dalam kode baru.

Mark Byers
sumber
5
Juga dimulai dengan Python 2.7 ia dapat menjatuhkan nomor indeks, yaitu menggunakan '{} in {}'string format biasa .
Cristian Ciupitu
121

Jika Anda menggunakan lebih dari satu argumen, argumen itu harus dalam tuple (perhatikan tanda kurung tambahan):

'%s in %s' % (unicode(self.author),  unicode(self.publication))

Seperti yang ditunjukkan EOL, unicode()fungsi biasanya mengasumsikan pengkodean ascii sebagai default, jadi jika Anda memiliki karakter non-ASCII, lebih aman untuk secara eksplisit meneruskan pengkodean:

'%s in %s' % (unicode(self.author,'utf-8'),  unicode(self.publication('utf-8')))

Dan pada Python 3.0, lebih disukai menggunakan str.format()sintaks sebagai gantinya:

'{0} in {1}'.format(unicode(self.author,'utf-8'),unicode(self.publication,'utf-8'))
Mark Cidade
sumber
60

Pada objek tuple / pemetaan untuk beberapa argumen format

Berikut ini adalah kutipan dari dokumentasi:

Diberikan format % values, %spesifikasi konversi formatdiganti dengan nol atau lebih elemen values. Efeknya mirip dengan penggunaan sprintf()dalam bahasa C.

Jika formatmembutuhkan argumen tunggal, nilai mungkin merupakan objek tunggal non-tupel. Jika tidak, nilai harus berupa tupel dengan jumlah item yang ditentukan oleh formatstring , atau objek pemetaan tunggal (misalnya, kamus).

Referensi


Di str.formatalih-alih%

Alternatif yang lebih baru untuk %operator adalah menggunakan str.format. Berikut kutipan dari dokumentasi:

str.format(*args, **kwargs)

Lakukan operasi pemformatan string. String tempat metode ini dipanggil dapat berisi teks literal atau bidang pengganti yang dibatasi oleh kurung kurawal {}. Setiap bidang pengganti berisi indeks numerik argumen posisi, atau nama argumen kata kunci. Mengembalikan salinan string di mana setiap bidang penggantian diganti dengan nilai string dari argumen yang sesuai.

Metode ini adalah standar baru dalam Python 3.0, dan harus lebih disukai untuk %memformat .

Referensi


Contohnya

Berikut ini beberapa contoh penggunaan:

>>> '%s for %s' % ("tit", "tat")
tit for tat

>>> '{} and {}'.format("chicken", "waffles")
chicken and waffles

>>> '%(last)s, %(first)s %(last)s' % {'first': "James", 'last': "Bond"}
Bond, James Bond

>>> '{last}, {first} {last}'.format(first="James", last="Bond")
Bond, James Bond

Lihat juga

polygenelubricants
sumber
Saya tidak punya cara untuk menguji ini (saya tidak tahu Python sebanyak itu), tetapi contoh-contoh tampaknya menyarankan bahwa sesuatu seperti '{self.author} in {self.publication}'.format(self=self)harus "bekerja". Saya hanya tidak yakin tentang unicodesemuanya.
polygenelubricants
1
Ya, Anda memang dapat mengakses atribut (dan juga indeks). Lihat docs.python.org/library/string.html#formatstrings Jadi, dalam contoh Anda, Anda bisa menggunakan {first[0]}untuk mendapatkan inisial J.
Duncan
10

Anda harus memasukkan nilai ke dalam tanda kurung:

'%s in %s' % (unicode(self.author),  unicode(self.publication))

Di sini, untuk pertama %syang unicode(self.author)akan ditempatkan. Dan untuk yang kedua %s, unicode(self.publication)akan digunakan.

Catatan: Anda harus mendukung string formattingatas %Notasi. Info lebih lanjut di sini

Bahadir Tasdemir
sumber
Aku tidak percaya bahwa orang-orang masih menyarankan %sketimbangformat
user1767754
8

Ada masalah yang signifikan dengan beberapa jawaban yang diposting sejauh ini: diterjemahkan unicode()dari pengodean default, yang seringkali ASCII; sebenarnya, unicode()mencoba membuat "rasa" dari byte yang diberikan dengan mengubahnya menjadi karakter. Dengan demikian, kode berikut, yang pada dasarnya adalah apa yang direkomendasikan oleh jawaban sebelumnya, gagal pada mesin saya:

# -*- coding: utf-8 -*-
author = 'éric'
print '{0}'.format(unicode(author))

memberi:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print '{0}'.format(unicode(author))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

Kegagalan berasal dari fakta bahwa authortidak hanya mengandung byte ASCII (yaitu dengan nilai dalam [0; 127]), dan unicode()menerjemahkan dari ASCII secara default (pada banyak mesin).

Solusi yang kuat adalah dengan secara eksplisit memberikan pengkodean yang digunakan di bidang Anda; menggunakan UTF-8 sebagai contoh:

u'{0} in {1}'.format(unicode(self.author, 'utf-8'), unicode(self.publication, 'utf-8'))

(atau tanpa inisial u, tergantung pada apakah Anda menginginkan hasil Unicode atau string byte).

Pada titik ini, orang mungkin ingin mempertimbangkan memiliki authordan publicationbidang menjadi string Unicode, alih-alih mendekode mereka selama memformat.

Eric O Lebigot
sumber
5

Untuk python2 Anda juga bisa melakukan ini

'%(author)s in %(publication)s'%{'author':unicode(self.author),
                                  'publication':unicode(self.publication)}

yang berguna jika Anda memiliki banyak argumen untuk diganti (terutama jika Anda melakukan internasionalisasi)

Python2.6 dan seterusnya mendukung .format()

'{author} in {publication}'.format(author=self.author,
                                   publication=self.publication)
John La Rooy
sumber
4

Anda juga dapat menggunakannya dengan bersih dan sederhana (tetapi salah! Karena Anda harus menggunakan formatseperti yang dikatakan Mark Byers) dengan melakukan:

print 'This is my %s formatted with %d arguments' % ('string', 2)
Lordn__n
sumber
3

Untuk kelengkapan, dalam python 3.6 f-string diperkenalkan pada PEP-498 . String ini memungkinkan untuk

menanamkan ekspresi di dalam string literal, menggunakan sintaks minimal.

Itu berarti bahwa untuk contoh Anda, Anda juga dapat menggunakan:

f'{self.author} in {self.publication}'
Westr
sumber