Định dạng chuỗi với f-string
Bạn sẽ học được
- Cú pháp f-string và vì sao nó thay thế
%và.format(). - Định dạng số: chữ số thập phân, phân cách hàng nghìn, phần trăm.
- Căn lề, độ rộng, đệm ký tự.
- Dùng biểu thức và gọi hàm bên trong dấu ngoặc.
- Mẹo debug
f"{bien=}"và các lỗi thường gặp.
Khái niệm cốt lõi
f-string (formatted string literal) ra mắt từ Python 3.6, đánh dấu bằng chữ f trước dấu nháy. Bên trong chuỗi, mọi thứ trong { } được đánh giá như biểu thức Python rồi chèn vào:
name = "An"
age = 28
print(f"Chào {name}, bạn {age} tuổi")Chào An, bạn 28 tuổiSo với hai cách cũ:
print("Chào " + name + ", bạn " + str(age) + " tuổi") # nối chuỗi
print("Chào {}, bạn {} tuổi".format(name, age)) # formatf-string ngắn hơn, không cần str(), và đọc gần với câu tiếng Việt. Đây là cách chuẩn trong mã hiện đại; hai cách kia chỉ còn trong code cũ.
Định dạng số
Sau biểu thức có thể thêm : và format spec:
x = 3.14159
print(f"Pi ≈ {x:.2f}")
print(f"{1234567:,}")
print(f"{0.1234:.1%}")Pi ≈ 3.14
1,234,567
12.3%| Spec | Ý nghĩa | Kết quả |
|---|---|---|
.2f | 2 chữ số thập phân | 3.14 |
, | Phân cách hàng nghìn | 1,234,567 |
.1% | Nhân 100, 1 chữ số thập phân, thêm % | 12.3% |
05d | Số nguyên, độ rộng 5, đệm 0 | 00042 |
e | Ký hiệu khoa học | 1.234000e+06 |
+d | Luôn hiện dấu | +42 |
Với tiền Việt Nam, dấu phân cách mặc định là dấu phẩy theo chuẩn Anh–Mỹ. Muốn định dạng kiểu Việt (1.234.567), dùng thư viện locale hoặc tự thay dấu — f-string một mình không đổi được ký tự phân cách.
Căn lề và độ rộng
name = "An"
print(f"[{name:>6}]")
print(f"[{name:<6}]")
print(f"[{name:^6}]")[ An]
[An ]
[ An ]> phải, < trái, ^ giữa. Số sau dấu hai chấm là tổng độ rộng. Có thể đệm bằng ký tự khác:
print(f"[{name:*^8}]")[***An***]Căn lề hữu ích khi in bảng trong terminal. Với bảng phức tạp hơn, dùng tabulate hoặc pandas thay vì tự canh.
Biểu thức trong dấu ngoặc
Bên trong { } là biểu thức đầy đủ, không chỉ tên biến:
price = 890000
quantity = 3
print(f"Tổng: {price * quantity:,} đồng")
print(f"Làm tròn: {round(price / 3, -3):,.0f}")
print(f"Viết hoa: {'data' * 2}")Tổng: 2,670,000 đồng
Làm tròn: 297,000
Viết hoa: datadataCó thể gọi hàm, dùng toán tử ba ngôi, truy cập dict — miễn biểu thức không chứa dấu hai chấm gây nhầm với format spec (khi đó bọc ngoặc đơn):
user = {"name": "An", "age": 28}
print(f"{user['name']} — {user['age']}")user['name'] dùng nháy đơn bên trong nháy kép của f-string. Từ Python 3.12, có thể dùng cùng loại nháy và dấu gạch chéo ngược trong biểu thức; với 3.10–3.11 phải né bằng cách đổi loại nháy.
Mẹo debug
Python 3.8+ cho phép = ngay sau biểu thức để in cả tên và giá trị:
name = "An"
age = 28
print(f"{name=}, {age=}")name='An', age=28Đây là cách nhanh nhất để kiểm tra biến khi debug, thay cho print("name:", name). Có thể kết hợp format spec: f"{age=:03d}" in age=028.
Chuỗi nhiều dòng
name = "An"
city = "Hà Nội"
text = f"""
Tên: {name}
Thành phố: {city}
"""
print(text)Ba dấu nháy giữ nguyên xuống dòng và thụt lề. Cẩn thận: thụt lề trong mã nguồn cũng vào chuỗi, nên đặt nội dung sát lề trái hoặc dùng textwrap.dedent.
Thực hành
- In
Pi ≈ 3.14từ3.14159bằng spec.2f. - Định dạng
1234567có dấu phẩy và0.1234thành12.3%. - In tên "An" căn phải, trái, giữa trong độ rộng 6.
- Tính
price * quantitytrực tiếp trong f-string với dấu phân cách. - Dùng
f"{bien=}"để in ba biến bất kỳ. - In một bảng ba dòng, ba cột căn trái, dùng f-string.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
In ra {name} nguyên văn | Thiếu chữ f trước chuỗi | Thêm f"..." |
ValueError: Invalid format specifier | Spec sai cú pháp | Kiểm tra phần sau : |
SyntaxError với nháy bên trong | Trùng loại nháy (Python < 3.12) | Đổi nháy ngoài hoặc trong |
KeyError trong f-string | Dict thiếu khóa | Dùng .get() có mặc định |
Số thực hiện 0.30000000000000004 | Sai số nhị phân | Định dạng .2f khi in |
Dấu phân cách là , không phải . | Chuẩn mặc định Anh–Mỹ | Dùng locale nếu cần kiểu Việt |
| Chuỗi nhiều dòng bị thụt lề | Thụt lề trong mã vào chuỗi | textwrap.dedent |
Tóm tắt
- f-string đánh giá biểu thức trong
{ }, thay thế nối chuỗi và.format(). - Format spec sau
:điều khiển số, phần trăm, căn lề, độ rộng. - Biểu thức trong ngoặc có thể gọi hàm và truy cập dict.
f"{bien=}"là mẹo debug nhanh.- Chú ý loại nháy khi biểu thức chứa chuỗi (Python < 3.12).
Dùng ← → để chuyển bài