Sử dụng nhiều đối số để định dạng chuỗi trong Python (ví dụ: '% s'% s ')


174

Tôi có một chuỗi trông giống như '%s in %s'và tôi muốn biết cách tách biệt các đối số sao cho chúng là hai% s khác nhau. Tâm trí của tôi đến từ Java đã nghĩ ra điều này:

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

Nhưng điều này không hoạt động, vậy nó trông như thế nào trong Python?

Câu trả lời:


191

Câu trả lời của Mark Cidade là đúng - bạn cần cung cấp một tuple.

Tuy nhiên, từ Python 2.6 trở đi, bạn có thể sử dụng formatthay vì %:

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

Việc sử dụng %để định dạng chuỗi không còn được khuyến khích.

Phương pháp định dạng chuỗi này là tiêu chuẩn mới trong Python 3.0 và nên được ưu tiên hơn định dạng% được mô tả trong Hoạt động định dạng chuỗi trong mã mới.


5
Cũng bắt đầu với Python 2.7, anh ta có thể bỏ số chỉ mục, tức là sử dụng '{} in {}'chuỗi định dạng đơn giản .
Cristian Ciupitu

121

Nếu bạn đang sử dụng nhiều hơn một đối số thì nó phải ở trong một tuple (lưu ý các dấu ngoặc đơn phụ):

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

Như EOL chỉ ra, unicode()hàm thường giả sử mã hóa ascii làm mặc định, vì vậy nếu bạn có các ký tự không phải ASCII, việc chuyển mã hóa rõ ràng sẽ an toàn hơn:

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

Và như Python 3.0, thay vào đó, nên sử dụng str.format()cú pháp:

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

60

Trên một đối tượng tuple / ánh xạ cho nhiều đối số format

Sau đây là đoạn trích từ tài liệu:

Cho trước format % values, %thông số kỹ thuật chuyển đổi formatđược thay thế bằng 0 hoặc nhiều yếu tố của values. Hiệu quả tương tự như việc sử dụng sprintf()trong ngôn ngữ C.

Nếu formatyêu cầu một đối số duy nhất, các giá trị có thể là một đối tượng không đơn lẻ. Nếu không, giá trị phải được một tuple với chính xác số lượng các mục theo quy định của formatchuỗi , hoặc một đối tượng duy nhất lập bản đồ (ví dụ, một cuốn từ điển).

Người giới thiệu


Trên str.formatthay vì%

Một thay thế mới hơn cho %nhà điều hành là sử dụng str.format. Đây là một đoạn trích từ tài liệu:

str.format(*args, **kwargs)

Thực hiện thao tác định dạng chuỗi. Chuỗi mà phương thức này được gọi có thể chứa văn bản bằng chữ hoặc các trường thay thế được phân tách bằng dấu ngoặc {}. Mỗi trường thay thế chứa chỉ mục số của đối số vị trí hoặc tên của đối số từ khóa. Trả về một bản sao của chuỗi trong đó mỗi trường thay thế được thay thế bằng giá trị chuỗi của đối số tương ứng.

Phương pháp này là tiêu chuẩn mới trong Python 3.0 và nên được ưu tiên %định dạng .

Người giới thiệu


Ví dụ

Dưới đây là một số ví dụ sử dụng:

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

Xem thêm


Tôi không có cách nào để kiểm tra điều này (tôi không biết Python nhiều như vậy), nhưng các ví dụ dường như gợi ý rằng một cái gì đó giống như '{self.author} in {self.publication}'.format(self=self)nên "hoạt động". Tôi chỉ không chắc chắn về tất cả unicodemọi thứ.
đa gen

1
Có, bạn thực sự có thể truy cập các thuộc tính (và cả các chỉ số). Xem docs.python.org/l Library / chuỗi.html # formatstrings Vì vậy, trong ví dụ của bạn, bạn có thể đã sử dụng {first[0]}để có được chữ cái đầu tiên J.
Duncan

10

Bạn chỉ cần đặt các giá trị vào trong ngoặc đơn:

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

Ở đây, cho là người đầu tiên %ssự unicode(self.author)sẽ được đặt. Và lần thứ hai %s, unicode(self.publication)sẽ được sử dụng.

Lưu ý: Bạn nên ủng hộ string formattingso với %Notation. Thêm thông tin ở đây


Tôi không thể tin rằng mọi người vẫn đề xuất %sthay vào đóformat
dùng1767754

8

Có một vấn đề đáng kể với một số câu trả lời được đăng cho đến nay: unicode()giải mã từ mã hóa mặc định, thường là ASCII; trong thực tế, unicode()cố gắng làm cho "ý nghĩa" của các byte được đưa ra bằng cách chuyển đổi chúng thành các ký tự. Do đó, đoạn mã sau, về cơ bản là những gì được đề xuất bởi các câu trả lời trước, đã thất bại trên máy của tôi:

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

cho:

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)

Lỗi này xuất phát từ thực tế là authorkhông chỉ chứa các byte ASCII (nghĩa là có các giá trị trong [0; 127]) và unicode()giải mã theo ASCII theo mặc định (trên nhiều máy).

Một giải pháp mạnh mẽ là cung cấp mã hóa rõ ràng được sử dụng trong các lĩnh vực của bạn; lấy UTF-8 làm ví dụ:

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

(hoặc không có chữ cái đầu tiên u, tùy thuộc vào việc bạn muốn kết quả Unicode hay chuỗi byte).

Tại thời điểm này, người ta có thể muốn xem xét việc có authorpublicationcác trường là các chuỗi Unicode, thay vì giải mã chúng trong quá trình định dạng.


5

Đối với python2, bạn cũng có thể làm điều này

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

sẽ hữu ích nếu bạn có nhiều đối số để thay thế (đặc biệt nếu bạn đang thực hiện quốc tế hóa)

Python2.6 trở đi hỗ trợ .format()

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

4

Bạn cũng có thể sử dụng nó sạch sẽ và đơn giản (nhưng sai! Vì bạn nên sử dụng formatnhư Mark Byers đã nói) bằng cách thực hiện:

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

3

Để hoàn thiện, trong chuỗi python 3.6 f được giới thiệu trong PEP-498 . Những chuỗi này làm cho nó có thể

biểu thức nhúng bên trong chuỗi ký tự, sử dụng cú pháp tối thiểu.

Điều đó có nghĩa là ví dụ của bạn, bạn cũng có thể sử dụng:

f'{self.author} in {self.publication}'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.