Python được đánh giá cao về khả năng xử lý dữ liệu. Một số tác vụ phổ biến nhất trong lập trình liên quan đến việc đọc, ghi hoặc thao tác dữ liệu. Do đó, nắm vững cách làm việc với các định dạng tệp khác nhau, vốn được dùng để lưu trữ nhiều loại dữ liệu, sẽ rất hữu ích.

Ví dụ, hãy xem xét một chương trình Python kiểm tra danh sách người dùng để kiểm soát truy cập. Danh sách người dùng của bạn có thể được lưu trong một tệp văn bản, cho phép bạn kiểm tra quyền truy cập hoặc chỉnh sửa quyền. Với Python, khả năng mở, đọc, ghi và đóng tệp sẽ giúp bạn thực hiện các tác vụ này.
Hướng dẫn này sẽ mô tả ngắn gọn một số định dạng tệp mà Python có thể xử lý. Sau phần giới thiệu ngắn gọn đó, bạn sẽ học cách xử lý tệp văn bản thuần túy trong Python 3. Khi hoàn tất, bạn sẽ có thể xử lý bất kỳ tệp văn bản thuần túy nào trong Python.
Điều kiện tiên quyết
Để thực hiện hướng dẫn này, bạn cần cài đặt Python 3 và thiết lập môi trường lập trình cục bộ trên máy tính. Nếu chưa có, bạn có thể thiết lập bằng cách làm theo hướng dẫn cài đặt và cấu hình phù hợp với hệ điều hành của mình:
- Ubuntu 22.04 hoặc Debian 8
- CentOS 7
- Mac OS X
- Windows 10
Kiến thức nền tảng
Python rất linh hoạt và có thể xử lý nhiều định dạng tệp khác nhau một cách dễ dàng, bao gồm nhưng không giới hạn ở các loại sau:
| Loại tệp | Mô tả |
|---|---|
| Plain text | Lưu trữ dữ liệu chỉ gồm các ký tự (chuỗi), không kèm bất kỳ siêu dữ liệu cấu trúc nào |
| CSV | Tệp giá trị phân tách bằng dấu phẩy (hoặc ký tự phân tách khác) để tổ chức dữ liệu, cho phép lưu trữ dữ liệu ở dạng bảng |
| HTML | Tệp HyperText Markup Language lưu dữ liệu có cấu trúc, dùng để hiển thị trên trình duyệt và thường được sử dụng cho trang web |
| JSON | JavaScript Object Notation, định dạng đơn giản và hiệu quả, là một trong những định dạng phổ biến nhất để lưu trữ và truyền dữ liệu có cấu trúc |
Hướng dẫn này sẽ tập trung vào việc làm việc với tệp văn bản thuần túy (plain text).
Bước 1: Tạo tệp văn bản
Trước khi bắt đầu làm việc trong Python, chúng ta cần có sẵn một tệp để xử lý. Mở trình soạn thảo mã và tạo một tệp văn bản thuần túy mới có tên days.txt.
Trong tệp mới, nhập một vài dòng liệt kê các ngày trong tuần:
days.txt
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Tiếp theo, lưu tệp và ghi nhớ vị trí của tệp. Trong ví dụ này, người dùng sammy lưu tệp tại /home/sammy/days.txt. Thông tin này sẽ rất quan trọng ở các bước sau khi chúng ta mở tệp trong Python.
Bây giờ, khi đã có tệp để xử lý, bạn có thể bắt đầu lập trình.
Bước 2: Mở tệp
Trong trình soạn thảo, tạo một tệp Python mới và đặt tên files.py.
Để mở một tệp trong Python, trước hết cần liên kết tệp trên ổ đĩa với một biến trong Python, quá trình này gọi là mở tệp và biến này gọi là file handle. Chúng ta bắt đầu bằng cách cho Python biết vị trí của tệp, còn được gọi là đường dẫn tệp (file path). Trong ví dụ này, đường dẫn là /home/sammy/days.txt. Tạo một biến để lưu thông tin đường dẫn này:
# files.py
path = '/home/sammy/days.txt'
Bây giờ, có thể sử dụng hàm open() của Python để mở tệp days.txt. Hàm open() cần đối số đầu tiên là đường dẫn tệp. Hàm này còn chấp nhận nhiều tham số khác, quan trọng nhất là tham số tùy chọn mode, một chuỗi xác định chế độ mở tệp. Chế độ mở phụ thuộc vào mục đích làm việc với tệp:
'r': đọc tệp'w': ghi đè nội dung tệp'a': ghi nối thêm vào cuối tệp'r+': vừa đọc vừa ghi vào cùng một tệp
Trong ví dụ này, chúng ta chỉ muốn đọc từ tệp, nên sẽ sử dụng chế độ 'r'. Hãy dùng hàm open() để mở tệp days.txt và gán đối tượng file handle trả về vào biến days_file.
# files.py
days_file = open(path, 'r')
Khi tệp đã được mở, bước tiếp theo sẽ là đọc nội dung của nó.
Bước 3: Đọc tệp
Sau khi mở tệp, chúng ta có thể thao tác với nó (đọc dữ liệu) thông qua biến đã gán. Python cung cấp ba thao tác liên quan để đọc thông tin từ tệp. Sau đây là cách hoạt động của mỗi thao tác.
Sử dụng read()
Phương thức read() trả về toàn bộ nội dung tệp dưới dạng một chuỗi duy nhất:
days_file.read()
Kết quả:
'Monday\\nTuesday\\nWednesday\\nThursday\\nFriday\\nSaturday\\nSunday\\n'
Lưu ý, ký tự \\n trong chuỗi trên đại diện cho ký tự xuống dòng (newline). Khi làm việc trực tiếp với Python (ví dụ khi bạn chạy lệnh python từ dòng lệnh), Python sẽ dùng \\n để hiển thị các dòng mới. Bạn cũng có thể dùng ký tự này để biểu thị một dòng mới khi tự tạo các chuỗi của riêng mình.
Sử dụng readline()
Phương thức readline() trả về dòng tiếp theo trong tệp, bao gồm ký tự xuống dòng. Nói cách khác, phương thức này đọc tệp theo từng dòng:
days_file.readline()
Kết quả:
'Monday\\n'
Khi bạn đọc một dòng bằng thao tác readline, vị trí hiện tại trong tệp mà Python sẽ đọc sẽ được chuyển sang dòng kế tiếp. Nếu bạn gọi lại thao tác này, nó sẽ trả về dòng tiếp theo trong tệp như sau:
days_file.readline()
Kết quả:
'Tuesday\\n'
Sử dụng readlines()
Phương thức readlines() trả về danh sách các dòng trong tệp, mỗi phần tử trong danh sách là một dòng:
days_file.readlines()
Kết quả:
['Monday\\n', 'Tuesday\\n', 'Wednesday\\n', 'Thursday\\n', 'Friday\\n', 'Saturday\\n', 'Sunday\\n']
Một điều bạn cần lưu ý khi đọc dữ liệu từ tệp là sau khi tệp đã được đọc bằng một trong các thao tác đọc trên, bạn sẽ không thể đọc lại dữ liệu đó.
Ví dụ, nếu bạn chạy days_file.read() trước, rồi tiếp tục gọi days_file.readlines() thì thao tác thứ hai sẽ trả về một chuỗi rỗng.
Do đó, mỗi khi bạn muốn đọc lại từ tệp, bạn sẽ cần mở một biến tệp mới hoặc sử dụng phương thức seek(), điều này nằm ngoài phạm vi của hướng dẫn này. Nếu muốn tìm hiểu thêm, Python có tài liệu hướng dẫn rất đầy đủ về các phương thức này.
Bây giờ, sau khi chúng ta đã đọc dữ liệu từ tệp, hãy tìm hiểu cách ghi dữ liệu vào một tệp mới.
Bước 4: Ghi vào một tệp
Trong bước này, bạn sẽ ghi vào một tệp mới với tiêu đề Days of the Week và nội dung từ tệp ban đầu. Trước tiên, tạo một biến tiêu đề:
# files.py
title = 'Days of the Week\\n'
Tiếp theo, lưu danh sách các ngày trong tuần vào một biến có tên days. Đoạn mã dưới đây mở tệp ở chế độ đọc, đọc toàn bộ nội dung tệp và lưu kết quả vào biến days. Để dễ theo dõi, phần mã từ Bước 2 được đưa lại:
# files.py
path = '/home/sammy/days.txt'
days_file = open(path, 'r')
days = days_file.read()
Bây giờ khi bạn đã có các biến cho tiêu đề và các ngày trong tuần, bạn có thể bắt đầu ghi dữ liệu vào tệp mới. Trước tiên, hãy xác định vị trí của tệp. Một lần nữa, chúng ta sẽ sử dụng thư mục /home/sammy/, vì vậy đường dẫn sẽ là /home/sammy/new_days.txt. Sau đó, bạn có thể mở tệp mới ở chế độ ghi bằng cách sử dụng hàm open() với chế độ 'w'.
# files.py
new_path = '/home/sammy/new_days.txt'
new_days = open(new_path, 'w')
Lưu ý, nếu new_days.txt đã tồn tại trước đó, nội dung cũ sẽ bị ghi đè khi mở tệp ở chế độ 'w'.
Sau khi mở tệp mới, bạn có thể thêm dữ liệu bằng phương thức write(). Phương thức này nhận một chuỗi và ghi vào tệp. Nếu muốn xuống dòng, bạn phải tự thêm ký tự xuống dòng \\n. Trong biến title đã có sẵn ký tự này ở cuối chuỗi 'Days of the Week\\n'.
Ghi tiêu đề vào tệp, sau đó ghi danh sách ngày trong tuần. Có thể thêm lệnh print() để theo dõi nội dung đang được ghi, đây là cách thường dùng khi kiểm tra tiến trình của script:
# files.py
new_days.write(title)
print(title)
new_days.write(days)
print(days)
Bước cuối cùng sau khi làm việc xong với một tệp là đóng tệp.
Bước 5: Đóng tệp
Đóng tệp giúp đảm bảo kết nối giữa tệp trên ổ đĩa và file handle được kết thúc, đồng thời cho phép các chương trình khác truy cập tệp và giữ an toàn cho dữ liệu. Nếu không sử dụng câu lệnh with như sẽ mô tả ở Bước 6, bạn luôn cần đóng tệp sau khi sử dụng.
Trong ví dụ này, đóng cả hai tệp bằng phương thức close():
# files.py
days_file.close()
new_days.close()
Khi script đã dùng xong các tệp, việc gọi close() sẽ giải phóng file handle tương ứng.
Bước 6: Sử dụng câu lệnh with (tùy chọn)
Bạn nên sử dụng một tính năng của ngôn ngữ gọi là câu lệnh with để làm việc với tệp trong Python (thường được gọi là cách “Pythonic”). Những câu lệnh này là cách viết rút gọn để thiết lập một ngữ cảnh mà trong đó công việc sẽ được thực hiện, và khi ngữ cảnh này kết thúc, các bước xử lý cuối cùng sẽ được tự động thực hiện để tránh những lỗi thường gặp. Trong trường hợp làm việc với tệp, câu lệnh with sẽ tự động đóng tệp để bạn không còn những file handle tồn tại sau khi hoàn thành tác vụ.
Giống như các khối lệnh khác trong Python (ví dụ: hàm, câu lệnh if, vòng lặp), câu lệnh with có dạng một câu lệnh đơn giản theo sau là dấu : và một khối mã thụt lề. Ví dụ sau mở một tệp và in nội dung của nó:
with open('/home/sammy/days.txt', 'r') as days_file:
days = days_file.read()
print(days)
Chúng ta sẽ đi qua từng bước để hiểu rõ hơn về cách hoạt động của đoạn mã này. Cũng như trước đó, chúng ta mở tệp bằng hàm tích hợp sẵn open() của Python, truyền vào đường dẫn tệp và các tham số mode. Tuy nhiên, vì chúng ta đang dùng câu lệnh with, thay vì gán file handle nhận được cho một biến bằng dấu =, chúng ta gán nó bằng từ khóa as. Đây là một phần của cú pháp đầy đủ của câu lệnh with:
with action as result:
...
Sau dấu :, chúng ta chuyển sang dòng tiếp theo và thụt đầu dòng, đây là cách Python tổ chức các khối chức năng. Giống như trước, chúng ta có quyền truy cập vào file handle thông qua biến days_file, vì vậy có thể gọi phương thức read() để lấy toàn bộ nội dung và dùng print() để in ra.
Lưu ý, ở đây không có lời gọi phương thức close(). Nguyên nhân là ngay khi mã lệnh thoát khỏi khối này (tức là khi dòng tiếp theo không còn thụt đầu dòng hoặc khi tệp kết thúc), ngữ cảnh của câu lệnh with sẽ tự động đóng tệp. Cách làm này không chỉ giúp bạn tránh phải nhớ đóng tệp sau mỗi lần sử dụng mà còn tách bạch rõ ràng toàn bộ logic xử lý tệp về mặt trực quan và logic trong khối mã. Nhờ đó, mã nguồn trở nên gọn gàng và dễ đọc hơn.
Sau khi đã hiểu rõ, chúng ta hãy viết lại đoạn mã trước đây bằng cách sử dụng câu lệnh with:
# files.py
with open(path, 'r') as days_file, open(new_path, 'w') as new_days:
days = days_file.read()
new_days.write(title)
new_days.write(days)
print(title)
print(days)
Bây giờ mã nguồn đã được tổ chức gọn gàng hơn nhiều. Chúng ta bắt đầu như trước bằng cách định nghĩa một số biến: đường dẫn của hai tệp và tiêu đề sẽ dùng để đặt ở phần đầu của tệp mới. Sau đó, chúng ta bắt đầu câu lệnh with, mở cả hai tệp và lưu kết nối của chúng vào các biến được đặt tên phù hợp. Giống như trước, chúng ta đọc nội dung của days_file, rồi ghi tiêu đề và nội dung đó vào new_days. Cuối cùng, chúng ta kết thúc khối bằng cách bỏ thụt đầu dòng để in ra giá trị của title và days mà chúng ta đã đọc.
Lưu ý, khác với một số khối lệnh khác trong Python, các biến được định nghĩa trong khối with vẫn có thể sử dụng bên ngoài khối.
Mặc dù vẫn có những trường hợp cần dùng phương thức close() như đã trình bày ở các bước trước, nhưng trong hầu hết tình huống làm việc với tệp trong Python, bạn sẽ sử dụng câu lệnh with.
Bước 7: Kiểm tra mã nguồn
Trước khi chạy mã, bạn cần kiểm tra để đảm bảo mọi thứ đã chính xác. Kết quả cuối cùng sẽ hiển thị như sau:
# files.py
path = '/home/sammy/days.txt'
new_path = '/home/sammy/new_days.txt'
title = 'Days of the week\\n'
with open(path, 'r') as days_file, open(new_path, 'w') as new_days:
days = days_file.read()
new_days.write(title)
new_days.write(days)
print(title)
print(days)
Sau khi lưu mã, mở terminal và chạy tập lệnh Python:
python files.py
Kết quả đầu ra sẽ là:
Days of the Week
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Bây giờ, hãy kiểm tra lại xem mã đã chạy chính xác chưa bằng cách mở tệp mới (new_days.txt). Nếu mọi thứ ổn, nội dung tệp sẽ là:
Days of the Week
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Kết luận
Trong hướng dẫn này, chúng ta đã tìm hiểu cách xử lý tệp văn bản thuần túy trong Python 3. Bạn đã biết cách mở, đọc, ghi và đóng tệp trong Python, từ đó có thể tiếp tục làm việc với dữ liệu của riêng mình. Python còn cung cấp nhiều phương thức hữu ích khác khi làm việc với nhập/xuất dữ liệu, và bạn có thể tìm hiểu thêm qua tài liệu chính thức.