Template tiêu đề file Python
Một mẹo nhỏ: Làm thế nào để tự động thêm thông tin header khi tạo file?
Thông qua: file > settings. Việc mở trang cài đặt bằng cách này khá dài dòng! Bạn có thể dùng: View > chọn Toolbar.
Hình ảnh minh họa các bước trên sẽ được chèn tại đây.
Kết quả sau khi thay đổi:
Hình ảnh minh họa kết quả sẽ được chèn tại đây.
1. Dòng đầu tiên của Python Script
Dòng này rất đơn giản, nó báo cho hệ thống biết nên dùng trình thông dịch nào. Nếu bạn chạy trực tiếp bằng lệnh python python_file_name.py thì dòng này không ảnh hưởng và có thể bỏ qua.
Tuy nhiên, nếu bạn muốn chạy trực tiếp thông qua ./python_file_name.py thì bắt buộc phải có!
Tại sao? Hãy lấy ví dụ với Linux và Windows.
- Linux: Mặc định, khi thực thi một file, Linux sử dụng
shelllàm trình thông dịch. Nếu bạn không chỉ định dùng Python, nó sẽ hiểu nhầm và dùngshellđể chạy, dẫn đến lỗi vìshellkhông hiểu cú pháp Python. - Windows: Tương tự, Windows mặc định dùng
powershelllàm trình thông dịch. Nếu không chỉ định, nó cũng sẽ báo lỗi.
2. Dòng thứ ba của Python Script
Dòng này là chú thích về tác giả của file, không cần giải thích quá nhiều.
Bây giờ chúng ta sẽ tập trung vào dòng thứ hai.
Giải thích chi tiết về mã hóa trong Python
Trong môi trường Python 2.7, chúng ta thường thấy dòng # -*- coding: utf-8 -*-. Tại sao phải thêm dòng này? Mục đích là để khai báo kiểu mã hóa cho file là UTF-8.
Trước hết, hãy đặt một câu hỏi: Tại sao chúng ta có thể nhìn thấy chữ, số, hình ảnh,... trên màn hình? Máy tính vốn chỉ hiểu các số 0 và 1, vậy làm thế nào chúng hiển thị được những nội dung này và chúng ta giao tiếp với chúng như thế nào?
Nếu chúng ta phải giao tiếp với máy tính bằng dãy 0 và 1, liệu chúng ta có thể đọc được những nội dung này không? Và còn một vấn đề nữa: các dãy nhị phân 0 và 1 hầu như không thể đọc được đối với con người, phải không?
Vậy làm thế nào để máy tính hiểu được ngôn ngữ của chúng ta và chúng ta hiểu được ngôn ngữ của máy tính?
Hãy tưởng tượng một cuốn từ điển Anh-Việt. Nó cho phép chúng ta dịch qua lại giữa hai ngôn ngữ. Máy tính cũng hoạt động tương tự, nó cần một bảng quy chiếu tiêu chuẩn. Bảng quy chiếu đầu tiên đó gọi là Bảng mã ASCII.
ASCII (American Standard Code for Information Interchange) là một hệ thống mã hóa ký tự dựa trên bảng chữ cái Latinh, được sử dụng chủ yếu để hiển thị tiếng Anh hiện đại và các ngôn ngữ Tây Âu khác. Đây là hệ thống mã hóa đơn byte phổ biến nhất hiện nay và tương đương với tiêu chuẩn quốc tế ISO/IEC 646.
Hình ảnh minh họa bảng mã ASCII sẽ được chèn tại đây.
Nhìn vào bảng trên, bạn có thể thấy:
- Có các ký tự đặc biệt, chữ hoa, chữ thường, số (lưu ý: các số từ 0-9 ở đây là ký tự).
- Mỗi ký tự này đều có một số thập phân tương ứng ở bên trái. Mặc dù máy tính không hiểu số thập phân, nhưng việc chuyển đổi giữa thập phân và nhị phân rất dễ dàng.
Bạn có thể xem bài viết trước của tôi về chuyển đổi thập phân và nhị phân.
Ví dụ: Nếu bạn nhấn phím 'A' trên bàn phím, thực tế bạn đang gửi số 65 đến máy tính. Thông qua cơ chế này, chúng ta có thể giao tiếp với bất kỳ máy tính nào. Thật tuyệt vời!
Một kiến thức quan trọng khác: Đơn vị nhỏ nhất trong máy tính là gì? Đó là bit. Một bit là một chữ số nhị phân, chỉ có thể là 0 hoặc 1.
Tuy nhiên, bit là đơn vị quá nhỏ, chúng ta thường dùng byte. Quy tắc chuyển đổi như sau:
''' 8 bit = 1 byte (8b = 1B) # Lưu ý: b (bit) viết thường, B (Byte) viết hoa 1024 byte = 1 Kilobyte (KB) 1024 Kilobyte = 1 Megabyte (MB) 1024 Megabyte = 1 Gigabyte (GB) 1024 Gigabyte = 1 Terabyte (TB) '''
Để lưu trữ một ký tự tiếng Anh, chúng ta cần ít nhất 1 byte (8 bit). Bảng ASCII có thể biểu diễn tất cả các ký tự cần thiết cho tiếng Anh chỉ với 1 byte, thật hiệu quả!
Tại sao lại như vậy? Bởi vì không gian lưu trữ của máy tính thời kỳ đầu rất đắt đỏ và hạn chế.
Một byte với 8 bit có thể lưu trữ tối đa 2^8 - 1 = 255 ký tự. Các nước phương Tây chỉ sử dụng 127 ký tự, số còn lại được dành cho việc mở rộng, dự phòng cho các quốc gia khác.
Tuy nhiên, vấn đề nảy sinh. Máy tính do người phương Tây phát minh ra, và 127 ký tự của ASCII là đủ để biểu diễn mọi thứ trong tiếng Anh. Nhưng họ đã không tính đến Trung Quốc! Khi ASCII đến Trung Quốc, chúng tôi nhận thấy rằng chỉ riêng các ký tự Trung Quốc thông dụng đã hơn 6000, hoàn toàn không đủ!
Người Trung Quốc đã rất thông minh: Họ đã mở rộng từ các bit dự phòng của ASCII để tạo ra các bảng mã riêng như GBK, GB2312, GB18030.
Họ đã mở rộng như thế nào? Ví dụ, tại vị trí 128 trong bảng ASCII, họ đã chỉ định một bảng mã riêng biệt khác. Thật thông minh!
Các quốc gia khác như Hàn Quốc, Nhật Bản cũng thiết kế bảng mã riêng của họ. Vấn đề là họ không quan tâm đến việc tương thích với nhau. Ví dụ, khi bạn tải một game Hàn Quốc về và cài đặt ở Trung Quốc, bạn sẽ thấy các ký tự bị lộn xộn (lỗi font). Tại sao?
Lỗi này thường do hai nguyên nhân:
- Không có bảng mã ký tự phù hợp.
- Xung đột bảng mã ký tự: Khi viết chương trình, họ dùng một bộ ký tự, còn máy tính của bạn lại dùng một bộ khác.
Không chỉ châu Á, mà châu Âu, châu Phi cũng gặp vấn đề tương tự. Để giải quyết tình trạng hỗn loạn này, tổ chức Internet quốc tế đã đề xuất một bảng mã thống nhất gọi là Unicode.
Unicode (Bộ mã thống nhất) là một tiêu chuẩn mã hóa ký tự máy tính. Nó được tạo ra để khắc phục những hạn chế của các hệ thống mã hóa truyền thống, bằng cách gán cho mỗi ký tự của mọi ngôn ngữ một mã nhị phân duy nhất và thống nhất. Unicode quy định rằng mọi ký tự và biểu tượng đều được biểu diễn bằng ít nhất 16 bit (2 byte), tức là 2^16 = 65536. Lưu ý: "Ít nhất 2 byte" có nghĩa là có thể nhiều hơn.
Tuy nhiên, vẫn còn một vấn đề: Việc tăng số byte sử dụng đồng nghĩa với việc không gian lưu trữ tăng lên gấp đôi. Ví dụ, cùng một văn bản tiếng Anh, nếu dùng ASCII chỉ tốn 1MB, thì dùng Unicode sẽ tốn ít nhất 2MB, thậm chí nhiều hơn.
Để giải quyết vấn đề này, UTF-8 ra đời.
UTF-8 là một kiểu nén và tối ưu hóa của Unicode. Nó không sử dụng cố định 2 byte cho mọi ký tự, mà phân loại chúng:
- Các ký tự trong bảng ASCII: dùng 1 byte.
- Các ký tự châu Âu: dùng 2 byte.
- Các ký tự Đông Á (như chữ Trung Quốc): dùng 3 byte.
Nhờ cơ chế linh hoạt này, việc lưu trữ trở nên hiệu quả hơn.
Tóm lại, chúng ta đã tìm hiểu:
- Bảng mã ASCII là gì.
- Bảng mã Unicode là gì.
- Bảng mã UTF-8 là gì.
Hãy nhớ lại nguyên nhân gây ra lỗi font: 1. Không có bảng mã phù hợp. 2. Xung đột bảng mã.
Quay lại vấn đề ban đầu: tại sao cần thêm dòng khai báo mã hóa? Trong Python phiên bản 2.x, khi biên dịch file .py, trình thông dịch mặc định sử dụng ASCII làm bảng mã. Vì vậy, nếu bạn không khai báo mã hóa trong Python 2.7 và viết một ký tự không nằm trong bảng ASCII, kết quả sẽ hiển thị lỗi.
Vấn đề này đã được giải quyết trong Python 3, vì Python 3 mặc định sử dụng Unicode.
Chuyển đổi mã hóa trong Python
Có một câu hỏi: Đã có Unicode thống nhất, tại sao vẫn cần chuyển đổi mã hóa? Mọi người dùng chung một bảng mã không phải tốt hơn sao?
1. Đây là một vấn đề kế thừa (legacy). Hãy thử hỏi: Nếu thế giới có một ngôn ngữ chung, liệu bạn có từ bỏ tiếng Việt để sử dụng ngôn ngữ đó không? Đây là một vấn nan giải.
2. Một trường hợp khác: Game Hàn Quốc khi vào thị trường Trung Quốc bị lỗi font. Dựa vào câu trả lời trên, chúng ta có thể suy luận: Người phát triển game đó có thể không tính đến việc xuất khẩu sang quốc gia khác. Nếu không có Unicode, chắc chắn game đó sẽ hiển thị lỗi khi đến Trung Quốc.
Do đó, cần phải chuyển đổi bảng mã của họ sang Unicode (UTF-8). Khi đó, chúng ta mới có thể hiển thị được tiếng Hàn một cách chính xác! (Lưu ý: đây chỉ là chuyển đổi bảng mã, không phải dịch thuật từ tiếng Hàn sang tiếng Trung).
1. Chuyển đổi mã hóa trong Python 3
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Tác giả: luotianshuai
text = 'Thiên Soái'
# Chuyển sang UTF-8
print(text.encode('UTF-8'))
# Chuyển sang GBK
print(text.encode('GBK'))
# Chuyển sang ASCII (Sẽ báo lỗi vì bảng ASCII không có ký tự 'Thiên Soái')
# print(text.encode('ASCII'))
2. Chuyển đổi mã hóa trong Python 2.x
Trong Python 2.x, mã hóa mặc định là ASCII. Bạn có thể khai báo mã hóa là UTF-8 ở đầu file, nhưng để chuyển từ UTF-8 sang GBK, bạn không thể chuyển trực tiếp. Bạn cần sử dụng Unicode làm trung gian.
Hình ảnh minh họa quy trình chuyển đổi sẽ được chèn tại đây.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Tác giả: luotianshuai
import chardet
text = 'Xin chào'
print(chardet.detect(text))
# Bước 1: Giải mã từ UTF-8 thành Unicode
# Bước 2: Mã hóa từ Unicode sang GBK
new_text = text.decode('UTF-8').encode('GBK')
print(chardet.detect(new_text))
# Kết quả
'''
{'confidence': 0.75249999999999995, 'encoding': 'utf-8'}
{'confidence': 0.35982121203616341, 'encoding': 'TIS-620'}
'''