การใช้อาร์กิวเมนต์หลายตัวสำหรับการจัดรูปแบบสตริงใน Python (เช่น '% s …% s')


174

ฉันมีสตริงที่ดูเหมือน'%s in %s'และต้องการทราบวิธีแยกอาร์กิวเมนต์เพื่อให้พวกเขาเป็นสอง% ที่แตกต่างกัน ใจของฉันมาจาก Java มากับสิ่งนี้:

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

แต่มันใช้ไม่ได้ผลมันดูเป็นงูใหญ่อย่างไร

คำตอบ:


191

คำตอบของ Mark Cidade นั้นถูกต้องคุณต้องจัดหาสิ่งอันดับ

อย่างไรก็ตามจาก Python 2.6 เป็นต้นไปคุณสามารถใช้formatแทน%:

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

ไม่สนับสนุนการใช้%สำหรับสตริงการจัดรูปแบบอีกต่อไป

วิธีการจัดรูปแบบสตริงนี้เป็นมาตรฐานใหม่ใน Python 3.0 และควรใช้กับการจัดรูปแบบ% ที่อธิบายไว้ในการดำเนินการจัดรูปแบบสตริงในรหัสใหม่


5
เริ่มต้นด้วย Python 2.7 เช่นกันเขาสามารถดร็อปดัชนีได้เช่นใช้'{} in {}'สตริงรูปแบบธรรมดา
Cristian Ciupitu

121

หากคุณใช้อาร์กิวเมนต์มากกว่าหนึ่งอาร์กิวเมนต์ต้องอยู่ในรูปแบบของ tuple (โปรดสังเกตเครื่องหมายวงเล็บพิเศษ):

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

เมื่อ EOL ชี้ให้เห็นunicode()ฟังก์ชั่นมักจะถือว่าการเข้ารหัส ASCII เป็นค่าเริ่มต้นดังนั้นหากคุณมีอักขระที่ไม่ใช่ ASCII จะปลอดภัยกว่าที่จะผ่านการเข้ารหัสอย่างชัดเจน:

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

และตั้งแต่ Python 3.0 เราขอแนะนำให้ใช้str.format()ไวยากรณ์แทน:

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

60

บนวัตถุ tuple / การแมปสำหรับหลายอาร์กิวเมนต์ format

ต่อไปนี้เป็นข้อความที่ตัดตอนมาจากเอกสาร:

ที่กำหนดformat % values, %ข้อกำหนดในการแปลงจะถูกแทนที่ด้วยศูนย์หรือมากกว่าองค์ประกอบของformat valuesเอฟเฟกต์นี้คล้ายคลึงกับการใช้งานsprintf()ในภาษา C

หากformatต้องการอาร์กิวเมนต์เดียวค่าอาจเป็นวัตถุที่ไม่ใช่ tuple เดียว มิฉะนั้นค่าต้อง tuple ตรงกับจำนวนรายการที่ระบุไว้โดยที่formatสตริง , หรือวัตถุที่ทำแผนที่เดียว (เช่นพจนานุกรม)

อ้างอิง


บนstr.formatแทน%

ทางเลือกใหม่ที่จะดำเนินการคือการใช้% str.formatนี่คือข้อความที่ตัดตอนมาจากเอกสาร:

str.format(*args, **kwargs)

ดำเนินการจัดรูปแบบสตริง {}สตริงกับวิธีการนี้เรียกว่าสามารถมีข้อความตัวอักษรหรือเปลี่ยนสาขาที่คั่นด้วยเครื่องหมายวงเล็บ แต่ละฟิลด์การแทนที่ประกอบด้วยดัชนีตัวเลขของอาร์กิวเมนต์ตำแหน่งหรือชื่อของอาร์กิวเมนต์คำหลัก ส่งคืนสำเนาของสตริงโดยที่แต่ละฟิลด์การแทนที่ถูกแทนที่ด้วยค่าสตริงของอาร์กิวเมนต์ที่สอดคล้องกัน

วิธีนี้เป็นมาตรฐานใหม่ในหลาม 3.0 และควรได้รับการแนะนำในการ%จัดรูปแบบ

อ้างอิง


ตัวอย่าง

นี่คือตัวอย่างการใช้งาน:

>>> '%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

ดูสิ่งนี้ด้วย


ฉันไม่มีวิธีทดสอบ (ฉันไม่รู้จัก Python มากนัก) แต่ตัวอย่างดูเหมือนจะแนะนำว่าสิ่งที่'{self.author} in {self.publication}'.format(self=self)ควร "ทำงาน" ฉันแค่ไม่แน่ใจเกี่ยวกับทั้งunicodeสิ่ง
polygenelubricants

1
ใช่คุณสามารถเข้าถึงแอตทริบิวต์ (และดัชนี) ได้อย่างแน่นอน ดูdocs.python.org/library/string.html#formatstrings ดังนั้นในตัวอย่างของคุณคุณจะได้ใช้เพื่อให้ได้เริ่มต้น{first[0]} J
ดันแคน

10

คุณต้องใส่ค่าลงในวงเล็บ:

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

นี่เป็นครั้งแรกจะถูกวางไว้ และสำหรับวินาทีที่จะใช้%sunicode(self.author)%sunicode(self.publication)

หมายเหตุ: คุณควรเห็นด้วยstring formattingกับ%สัญกรณ์ ข้อมูลเพิ่มเติมที่นี่


ฉันไม่อยากจะเชื่อเลยว่าผู้คนยังคงแนะนำ%sค่อนข้างformat
user1767754

8

มีปัญหาสำคัญกับคำตอบบางส่วนที่โพสต์แล้ว: unicode()ถอดรหัสจากการเข้ารหัสเริ่มต้นซึ่งมักจะเป็น ASCII; ในความเป็นจริงunicode()พยายามที่จะทำให้ "ความรู้สึก" ของไบต์ที่ได้รับโดยการแปลงพวกเขาเป็นตัวละคร ดังนั้นรหัสต่อไปนี้ซึ่งเป็นสิ่งที่แนะนำโดยคำตอบก่อนหน้านี้ล้มเหลวในเครื่องของฉัน:

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

ให้:

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)

ความล้มเหลวมาจากข้อเท็จจริงที่authorไม่มีไบต์ ASCII เท่านั้น (เช่นมีค่าใน [0; 127]) และunicode()ถอดรหัสจาก ASCII โดยค่าเริ่มต้น (บนเครื่องหลายเครื่อง)

โซลูชันที่แข็งแกร่งคือการให้การเข้ารหัสที่ใช้ในสาขาของคุณอย่างชัดเจน ใช้ UTF-8 เป็นตัวอย่าง:

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

(หรือไม่มีค่าเริ่มต้นuขึ้นอยู่กับว่าคุณต้องการผลลัพธ์ Unicode หรือสตริงไบต์)

ณ จุดนี้เราอาจต้องการพิจารณาให้มีauthorและpublicationฟิลด์เป็นสตริง Unicode แทนที่จะถอดรหัสระหว่างการจัดรูปแบบ


5

สำหรับ python2 คุณสามารถทำได้

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

ซึ่งมีประโยชน์ถ้าคุณมีข้อโต้แย้งมากมายที่จะทดแทน (โดยเฉพาะถ้าคุณกำลังทำให้เป็นสากล)

Python2.6 เป็นต้นไปรองรับ .format()

'{author} in {publication}'.format(author=self.author,
                                   publication=self.publication)

4

คุณสามารถใช้มันได้อย่างสะอาดและเรียบง่าย (แต่ผิด! เพราะคุณควรใช้formatเหมือนที่ Mark Byers พูด) โดยทำ:

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

3

เพื่อความสมบูรณ์ในหลาม 3.6-f สตริงจะถูกนำมาใช้ในPEP-498 สตริงเหล่านี้ทำให้มันเป็นไปได้

ฝังนิพจน์ภายในตัวอักษรของสตริงโดยใช้ไวยากรณ์ที่น้อยที่สุด

นั่นหมายความว่าสำหรับตัวอย่างของคุณคุณสามารถใช้:

f'{self.author} in {self.publication}'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.