2013-03-03 28 views
26

Tại sao tôi không thể sử dụng tuple làm đối số để định dạng theo kiểu mới ("string" .format())? Nó hoạt động tốt trong phong cách cũ ("chuỗi"%)?Định dạng kiểu mới với tuple làm đối số

Mã này hoạt động:

>>> tuple = (500000, 500, 5) 
... print "First item: %d, second item: %d and third item: %d." % tuple 

    First item: 500000, second item: 500 and third item: 5. 

Và đây không:

>>> tuple = (500000, 500, 5) 
... print("First item: {:d}, second item: {:d} and third item: {:d}." 
...  .format(tuple)) 

    Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    ValueError: Unknown format code 'd' for object of type 'str' 

Ngay cả với {r!}

>>> tuple = (500000, 500, 5) 
... print("First item: {!r}, second item: {!r} and third item: {!r}." 
...  .format(tuple)) 

    Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    IndexError: tuple index out of range 

Mặc dù nó hoạt động với cách mà:

>>> print("First item: {!r}, second item: {!r} and third item: {!r}." 
...  .format(500000, 500, 50)) 

    First item: 500000, second item: 500 and third item: 5. 

Trả lời

45

Cách định dạng cũ được sử dụng toán tử nhị phân, %. Theo bản chất của nó, nó chỉ có thể chấp nhận hai đối số. Cách định dạng mới sử dụng phương thức. Các phương thức có thể lấy bất kỳ số lượng đối số nào.

Vì đôi khi bạn cần phải chuyển nhiều thứ để định dạng và hơi vụng về để tạo tuple với một mục mọi lúc, kiểu cũ theo kiểu hack: nếu bạn chuyển nó thành bộ tuple, nó sẽ sử dụng nội dung của bộ dữ liệu như những thứ cần định dạng. Nếu bạn vượt qua nó một cái gì đó khác hơn là một tuple, nó sẽ sử dụng đó là điều duy nhất để định dạng.

Cách mới không cần hack như vậy: vì nó là một phương pháp, nó có thể lấy bất kỳ số lượng đối số nào. Như vậy, nhiều thứ cần định dạng sẽ cần được chuyển thành các đối số riêng biệt. May mắn thay, bạn có thể giải nén một tuple vào lập luận sử dụng *:

print("First item: {:d}, second item: {:d} and third item: {:d}.".format(*tuple)) 
17

Như icktoofay giải thích, theo phong cách cũ của định dạng, nếu bạn thông qua trong một tuple, Python sẽ tự động giải nén nó.

Tuy nhiên, bạn không thể sử dụng tuple với phương thức str.format vì Python cho rằng bạn chỉ chuyển qua một đối số. Bạn sẽ phải giải nén tuple bằng toán tử * để truyền vào từng phần tử dưới dạng đối số riêng lẻ.

>>> t = (500000, 500, 5) 
>>> "First item: {:d}, second item: {:d} and third item: {:d}.".format(*t) 
First item: 500000, second item: 500 and third item: 5. 

Ngoài ra, bạn có thể để ý tôi đổi tên biến tuple của bạn để t - không sử dụng tên BUILTIN cho các biến, như bạn sẽ ghi đè lên họ và có thể gây ra vấn đề xuống đường đua.

+3

+1 để đổi tên biến. –

+1

@Volatility Tôi nghĩ rằng {: d} là không cần thiết. Nếu bạn muốn đặt hàng dữ liệu, bạn có thể sử dụng đơn giản {} hoặc chỉ định thứ tự với chỉ mục hoặc dữ liệu trong tuple {0} {1} {2} – GeoStoneMarten

+0

@GeoStoneMarten trong khi tôi đồng ý, bằng cách sử dụng '{: d}' cho biết rõ ràng hơn rằng bạn muốn có một số thập phân ở đó (cho người khác đọc mã của bạn) – Petzku

0

Nó thực sự là có thể sử dụng một tuple như một cuộc tranh cãi để format(), nếu bạn tự chỉ mục các tuple bên trong dấu ngoặc nhọn:

>>> t = (500000, 500, 5) 
>>> print("First item: {0[0]:d}, second item: {0[1]:d} and third item: {0[2]:d}.".format(t)) 
First item: 500000, second item: 500 and third item: 5. 

Tôi tìm thấy điều này rõ ràng ít hơn so với phương pháp *, mặc dù.

Các vấn đề liên quan