!s
, và anh em của nó !a
và !r
áp dụng str()
, ascii()
và repr()
tương ứng trước suy và định dạng. Chúng được gọi là cờ chuyển đổi, và là một phần của Format String Syntax spec, không phải là per-field formatting spec áp dụng cho giá trị khi nội suy:
Các chuyển đổi lĩnh vực gây ra một kiểu ép buộc trước khi định dạng. Thông thường, công việc định dạng một giá trị được thực hiện theo phương thức __format__()
của chính giá trị đó. Tuy nhiên, trong một số trường hợp, việc ép buộc một kiểu được định dạng thành chuỗi là bắt buộc, sẽ ghi đè định nghĩa định dạng của riêng nó. Bằng cách chuyển đổi giá trị thành chuỗi trước khi gọi __format__()
, logic định dạng thông thường bị bỏ qua.
Mỏ nhấn mạnh đậm.
:s
chỉ áp dụng sau đó cho kết quả chuyển đổi (hoặc đối tượng gốc nếu không có chuyển đổi nào được áp dụng) và chỉ khi phương thức __format__
cho loại đối tượng hỗ trợ tùy chọn định dạng đó. Thông thường, chỉ các đối tượng thuộc loại str
mới hỗ trợ trình định dạng này; nó có ở dạng mặc định, chủ yếu là vì Format Specification Mini-Language cho phép sự tồn tại của một ký tự loại và vì cũ hơn %
printf
-style formatting có định dạng %s
. Nếu bạn đã cố gắng áp dụng loại s
cho một đối tượng không hỗ trợ nó, bạn sẽ nhận được một ngoại lệ.
Sử dụng !s
(hoặc !a
hoặc !r
) khi bạn có một đối tượng đó không phải là bản thân một chuỗi và một trong hai không hỗ trợ định dạng khác (không phải tất cả các loại làm) hoặc sẽ định dạng khác so với họ str()
, ascii()
hoặc repr()
chuyển đổi:
>>> class Foo:
... def __str__(self):
... return "Foo as a string"
... def __repr__(self):
... return "<Foo as repr, with åéæ some non-ASCII>"
... def __format__(self, spec):
... return "Foo formatted to {!r} spec".format(spec)
...
>>> print("""\
... Different conversions applied:
... !s: {0!s:>60s}
... !r: {0!r:>60s}
... !a: {0!a:>60s}
... No conversions: {0:>50s}
... """.format(Foo()))
Different conversions applied:
!s: Foo as a string
!r: <Foo as repr, with åéæ some non-ASCII>
!a: <Foo as repr, with \xe5\xe9\xe6 some non-ASCII>
No conversions: Foo formatted to '>50s' spec
Lưu ý: tất cả các định dạng được theo quy định của spec định dạng này thuộc trách nhiệm của phương pháp __format__
; dòng cuối cùng không áp dụng thao tác căn chỉnh trong thông số định dạng >50s
, phương pháp Foo.__format__
chỉ sử dụng phương thức này làm văn bản chữ trong thao tác định dạng (sử dụng chuyển đổi !r
tại đây). Mặt khác, đối với các giá trị được chuyển đổi, phương pháp str.__format__
được sử dụng và đầu ra được căn chỉnh ở bên phải trong trường rộng 50 ký tự, được đệm bằng dấu cách ở bên trái.
"Trường chuyển đổi" tự nói lên. – iFlo
'" .. ". Định dạng (..)' là ** luôn luôn ** một chuỗi. Bản demo 'type()' của bạn có ý nghĩa rất ít trong ngữ cảnh này, vì nó sẽ * luôn luôn giống nhau * bất kể thông số định dạng hoặc chuyển đổi nào đã được áp dụng cho các đối tượng đã định dạng. –
Ngoài ra, còn có các loại thông số định dạng khác sẽ tăng ngoại lệ, ngay cả khi bạn áp dụng chuyển đổi '! S', như' i'. –