Thao tác với file trong Python

Thao tác với file trong Python

Phan Nhật Chánh

Chánh20 tháng 05, 2021

13 min read
·
views
·
likes

Trong Python, file được xử lý bằng cách sử dụng module os, sys, và built-in module open(). Module os cho phép thao tác với file trong hệ thống, bao gồm tạo, xóa và di chuyển file. Module sys cho phép truy cập các đối số được truyền vào dòng lệnh khi chương trình Python được thực thi. Module open() cho phép mở và đóng file, đọc và ghi dữ liệu vào file.

Trong Python, file có thể được mở trong chế độ đọc (read), ghi (write) hoặc cập nhật (append). Khi một file được mở, nó sẽ được đại diện bởi một đối tượng file trong Python. Chúng ta có thể sử dụng các phương thức của đối tượng file này để đọc hoặc ghi dữ liệu vào file.

Các loại file phổ biến trong Python bao gồm văn bản (text file), tệp nhị phân (binary file) và tệp CSV (comma-separated values). Văn bản file chứa dữ liệu được lưu trữ dưới dạng văn bản đơn giản, trong khi tệp nhị phân chứa dữ liệu được mã hóa theo định dạng nhị phân. Tệp CSV là một loại tệp văn bản, trong đó dữ liệu được phân cách bằng dấu phẩy.

Việc làm việc với file trong Python rất quan trọng, vì nó cho phép chúng ta lưu trữ và truy xuất dữ liệu từ các tệp với các định dạng khác nhau.

Chúng ta thường lưu trữ dữ liệu của mình dưới các định dạng file khác nhau như .txt, .json, .xml, .csv, .tsv, .xlsx). Trong phần này, ta sẽ làm quen với cách xử lý file (tệp tin) trong python. Đầu tiên, chúng ta hãy làm quen với việc xử lý các file có định dạng phổ biến nhất là .txt

Xử lý file là một phần không thể thiếu khi lập trình, đôi lúc bạn sẽ phải thực hiện các thao tác như tạo file, đọc file, cập nhật file và xóa file. Trong python mở một tệp tin để xử lý dữ liệu chúng ta sẽ sử dụng hàm được tích hợp sẵn open()

# Syntax open('filename', mode) # mode(r, a, w, x, t,b) là các chế độ như đọc, ghi, xóa,...
# Syntax open('filename', mode) # mode(r, a, w, x, t,b) là các chế độ như đọc, ghi, xóa,...
  • Một số chế độ (mode) xử lý để làm việc với file trong python:
    • 'r' - Read - Giá trị mặc định. Mở tệp để đọc, lỗi nếu tệp không tồn tại.
    • 'a' - Append - Mở tệp để nối thêm (cập nhật thêm), tự tạo tệp nếu tệp đó không tồn tại.
    • 'w' - Write - Mở tệp để ghi, tạo tệp nếu tệp đó không tồn tại.
    • 'x' - Create - Tạo tệp được chỉ định, trả về lỗi nếu tệp tồn tại.
    • 't' - Text - Chế độ văn bản (Giá trị mặc định).
    • 'b' - Binary - Chế độ nhị phân (ví dụ: hình ảnh).
    • '+' - Mở tệp để cập nhật (đọc và ghi).

Bạn cũng nên xem thêm phần xử lý file trong python mà tôi đã giới thiệu ở phần nhập xuất dữ liệu để hiểu rõ hơn.

Mở file để đọc

Chế độ mở mặc định là đọc, vì vậy chúng ta không chỉ định 'r' hoặc 'rt'. Như vậy, bạn đã tạo và lưu một file có tên là read_file_example.txt trong thư mục. Hãy xem đoạn code dưới đây hoạt động như thế nào:

f = open('./files/reading_file_example.txt') print(f) # <_io.TextIOWrapper name='./files/reading_file_example.txt' mode='r' encoding='UTF-8'>
f = open('./files/reading_file_example.txt') print(f) # <_io.TextIOWrapper name='./files/reading_file_example.txt' mode='r' encoding='UTF-8'>

Như bạn có thể thấy trong ví dụ trên, bạn đã print tệp đã mở và nó hiển thị cho bạn một số thông tin về tệp đó. Tệp được mở có các phương thức đọc khác nhau như: read()read(), readline()readline(), readlines()readlines(). Một tệp đã mở phải được đóng bằng phương thức close()close().

read()

Đọc toàn bộ nội dung dưới dạng chuỗi (xem lại bài viết về string trong python). Nếu chúng ta muốn giới hạn số ký tự mà chúng ta đọc, bạn có thể giới hạn nó bằng cách chuyển đổi từ string sang int.

f = open('./files/reading_file_example.txt') txt = f.read() print(type(txt)) print(txt) f.close() # output # <class 'str'> # This is an example to show how to open a file and read. # This is the second line of the text.
f = open('./files/reading_file_example.txt') txt = f.read() print(type(txt)) print(txt) f.close() # output # <class 'str'> # This is an example to show how to open a file and read. # This is the second line of the text.

Thay vì hiển thị tất cả nội dung, chúng ta hãy lấy ra 10 ký tự đầu tiên của file.

f = open('./files/reading_file_example.txt') txt = f.read(10) print(type(txt)) print(txt) f.close() # output # <class 'str'> # This is an
f = open('./files/reading_file_example.txt') txt = f.read(10) print(type(txt)) print(txt) f.close() # output # <class 'str'> # This is an

readline()

Phương thức này chỉ sẽ trả về kết quả của dòng đầu tiên

f = open('./files/reading_file_example.txt') line = f.readline() print(type(line)) print(line) f.close() # output # <class 'str'> # This is an example to show how to open a file and read.
f = open('./files/reading_file_example.txt') line = f.readline() print(type(line)) print(line) f.close() # output # <class 'str'> # This is an example to show how to open a file and read.

readlines()

Phương thức này sẽ đọc tất cả các dòng có trong tệp và trả về một list (mỗi dòng là một phần tử của list)

f = open('./files/reading_file_example.txt') lines = f.readlines() print(type(lines)) print(lines) f.close() # output # <class 'list'> # ['This is an example to show how to open a file and read.\n', 'This is the second line of the text.']
f = open('./files/reading_file_example.txt') lines = f.readlines() print(type(lines)) print(lines) f.close() # output # <class 'list'> # ['This is an example to show how to open a file and read.\n', 'This is the second line of the text.']

Ngoài ra, Một cách khác để lấy tất cả các dòng trong file để đưa vào list ta có thể sử dụng phương thức splitlines()splitlines()

f = open('./files/reading_file_example.txt') lines = f.read().splitlines() print(type(lines)) print(lines) f.close() # output # <class 'list'> # ['This is an example to show how to open a file and read.', 'This is the second line of the text.']
f = open('./files/reading_file_example.txt') lines = f.read().splitlines() print(type(lines)) print(lines) f.close() # output # <class 'list'> # ['This is an example to show how to open a file and read.', 'This is the second line of the text.']

Sau khi mở một tệp, phần lớn chúng ta thường quên sử dụng close()close() để đóng file lại. Python cung cấp cho bạn một phương thức with bạn có thể sử dụng nó nếu bạn thường xuyên quên đóng file bằng close()close(). Hãy viết lại ví dụ trước trên phương thức with như sau:

with open('./files/reading_file_example.txt') as f: lines = f.read().splitlines() print(type(lines)) print(lines) # output # <class 'list'> # ['This is an example to show how to open a file and read.', 'This is the second line of the text.']
with open('./files/reading_file_example.txt') as f: lines = f.read().splitlines() print(type(lines)) print(lines) # output # <class 'list'> # ['This is an example to show how to open a file and read.', 'This is the second line of the text.']

Mở tệp để ghi và cập nhật

Để ghi vào một tệp hiện có, chúng ta phải thêm một chế độ làm tham số cho hàm open()open() như sau:

  • 'a' - append - sẽ nối thêm vào cuối tệp, nếu tệp không tồn tại, nó sẽ báo FileNotFoundError.
  • 'w' - write - sẽ ghi đè lên bất kỳ nội dung hiện có nào, nếu tệp không tồn tại thì nó sẽ tạo ra.

Hãy nối một số nội dung vào tệp mà chúng ta đang đọc:

with open('./files/reading_file_example.txt','a') as f: f.write('This text has to be appended at the end')
with open('./files/reading_file_example.txt','a') as f: f.write('This text has to be appended at the end')

Đoạn mã dưới đây sẽ tạo một tệp mới, nếu tệp không tồn tại:

with open('./files/writing_file_example.txt','w') as f: f.write('This text will be written in a newly created file')
with open('./files/writing_file_example.txt','w') as f: f.write('This text will be written in a newly created file')

Xóa file

Trong phần trước chúng ta đã biết cách tạo và xóa thư mục bằng cách sử dụng module os. Tương tự, để xóa một tệp, chúng ta cũng sử dụng module os.

import os os.remove('./files/example.txt')
import os os.remove('./files/example.txt')

Nếu tệp không tồn tại, phương thức remove()remove() sẽ gây ra lỗi, vì vậy tốt nhất là bạn nên sử dụng câu lệnh điều kiện như sau:

import os if os.path.exist('./files/example.txt'): os.remove('./files/example.txt') else: os.remove('The file does not exist')
import os if os.path.exist('./files/example.txt'): os.remove('./files/example.txt') else: os.remove('The file does not exist')

Các kiểu tệp tin

txt

Tệp có phần mở rộng .txt là một dạng dữ liệu rất phổ biến mà chúng ta đã trình bày trong phần trước (bạn có thể xem lại cách xử lý tệp tin txt). Hãy chuyển sang tệp JSON

json

JSON là viết tắt của JavaScript Object Notation. Trên thực tế, đó là một đối tượng JavaScript được chuỗi hóa. Ví dụ:

# dictionary person_dct= { "name":"Chanh", "country":"Viet Nam", "city":"Ha Noi", "skills":["JavaScrip", "React","Python"] } # JSON: Một chuỗi từ một dictionary person_json = "{'name': 'Chanh', 'country': 'Viet Nam', 'city': 'Ha Noi', 'skills': ['JavaScrip', 'React', 'Python']}" # sử dụng ba 3 dấu nháy kép làm ghi chú person_json = '''{ "name":"Chanh", "country":"Viet Nam", "city":"Ha Noi", "skills":["JavaScrip", "React","Python"] }'''
# dictionary person_dct= { "name":"Chanh", "country":"Viet Nam", "city":"Ha Noi", "skills":["JavaScrip", "React","Python"] } # JSON: Một chuỗi từ một dictionary person_json = "{'name': 'Chanh', 'country': 'Viet Nam', 'city': 'Ha Noi', 'skills': ['JavaScrip', 'React', 'Python']}" # sử dụng ba 3 dấu nháy kép làm ghi chú person_json = '''{ "name":"Chanh", "country":"Viet Nam", "city":"Ha Noi", "skills":["JavaScrip", "React","Python"] }'''
  • Đổi từ JSON sang Dictionary: Để chuyển đổi một JSON thành một dictionary, trước tiên chúng ta sẽ import module json (xem lại cách sử dụng module trong python) và sau đó chúng ta sử dụng phương thức loads()loads()
import json # JSON person_json = '''{ "name": "Chanh", "country": "Viet Nam", "city": "Ha Noi", "skills": ["JavaScrip", "React", "Python"] }''' # đổi từ JSON thành dictionary person_dct = json.loads(person_json) print(person_dct) print(person_dct['name']) # output # {'name': 'Chanh', 'country': 'Viet Nam', 'city': 'Ha Noi', 'skills': ['JavaScrip', 'React', 'Python']} # Chanh
import json # JSON person_json = '''{ "name": "Chanh", "country": "Viet Nam", "city": "Ha Noi", "skills": ["JavaScrip", "React", "Python"] }''' # đổi từ JSON thành dictionary person_dct = json.loads(person_json) print(person_dct) print(person_dct['name']) # output # {'name': 'Chanh', 'country': 'Viet Nam', 'city': 'Ha Noi', 'skills': ['JavaScrip', 'React', 'Python']} # Chanh
  • Đổi từ Dictionary sang JSON: Để thay đổi Dictionary thành JSON, chúng ta sử dụng phương thức dumps()dumps() từ mô-đun json.
import json # python dictionary person = { "name": "Chanh", "country": "Viet Nam", "city": "Ha Noi", "skills": ["JavaScrip", "React", "Python"] } # chuyển sang json person_json = json.dumps(person, indent=4) # indent could be 2, 4, 8. It beautifies the json print(type(person_json)) print(person_json) # output # JSON không có kiểu, nó là kiểu chuỗi. # <class 'str'> # { # "name": "Chanh", # "country": "Viet Nam", # "city": "Ha Noi", # "skills": [ # "JavaScrip", # "React", # "Python" # ] # }
import json # python dictionary person = { "name": "Chanh", "country": "Viet Nam", "city": "Ha Noi", "skills": ["JavaScrip", "React", "Python"] } # chuyển sang json person_json = json.dumps(person, indent=4) # indent could be 2, 4, 8. It beautifies the json print(type(person_json)) print(person_json) # output # JSON không có kiểu, nó là kiểu chuỗi. # <class 'str'> # { # "name": "Chanh", # "country": "Viet Nam", # "city": "Ha Noi", # "skills": [ # "JavaScrip", # "React", # "Python" # ] # }
  • Lưu file dưới dạng tệp JSON: Chúng ta có thể lưu trữ dữ liệu của mình dưới dạng json. Hãy lưu nó bằng đoạn code sau:
import json # python dictionary person = { "name": "Asabeneh", "country": "Finland", "city": "Helsinki", "skills": ["JavaScrip", "React", "Python"] } with open('./files/json_example.json', 'w', encoding='utf-8') as f: json.dump(person, f, ensure_ascii=False, indent=4)
import json # python dictionary person = { "name": "Asabeneh", "country": "Finland", "city": "Helsinki", "skills": ["JavaScrip", "React", "Python"] } with open('./files/json_example.json', 'w', encoding='utf-8') as f: json.dump(person, f, ensure_ascii=False, indent=4)

Trong đoạn code trên, chúng ta sử dụng encoding='utf-8'indent=4 (thụt đầu dòng). Thụt lề giúp dễ đọc file json hơn.

csv

CSV là viết tắt của cụm từ Comma Separated Values (các giá trị được phân tách bằng dấu phẩy) mà ở phần trước chúng ta cũng đã tìm hiểu cơ bản cách sử dụng Pandas để đọc và khám phá dữ liệu với tệp csv. CSV là một định dạng tệp đơn giản được sử dụng để lưu trữ dữ liệu dưới dạng bảng, chẳng hạn như bảng tính hoặc cơ sở dữ liệu. CSV là một định dạng dữ liệu rất phổ biến trong data science.

Ví dụ đây là nội dụng của file csv_example.csv

"name","country","city","skills" "Chanh","Viet Nam","Ha Noi","JavaScrip"

Ví dụ:

import csv with open('./files/csv_example.csv') as f: csv_reader = csv.reader(f, delimiter=',') # sử dụng reader() để đọc csv line_count = 0 for row in csv_reader: if line_count == 0: print(f'Column names are :{", ".join(row)}') line_count += 1 else: print( f'\t{row[0]} is a teachers. He lives in {row[1]}, {row[2]}.') line_count += 1 print(f'Number of lines: {line_count}') # output: # Column names are :name, country, city, skills # Chanh is a teacher. He lives in Viet Nam, Ha Noi. # Number of lines: 2
import csv with open('./files/csv_example.csv') as f: csv_reader = csv.reader(f, delimiter=',') # sử dụng reader() để đọc csv line_count = 0 for row in csv_reader: if line_count == 0: print(f'Column names are :{", ".join(row)}') line_count += 1 else: print( f'\t{row[0]} is a teachers. He lives in {row[1]}, {row[2]}.') line_count += 1 print(f'Number of lines: {line_count}') # output: # Column names are :name, country, city, skills # Chanh is a teacher. He lives in Viet Nam, Ha Noi. # Number of lines: 2

xlsx

Để đọc các tệp excel, chúng ta cần cài đặt package có tên xlrd. Bạn cần tham khảo cách install một package sử dụng pip.

xml

XML là một định dạng dữ liệu có cấu trúc khác trông giống như HTML. Trong XML, các thẻ không được xác định trước. Dòng đầu tiên là dòng khai báo trong XML. Person là tags (thẻ) gốc của file XML dưới đây. Ví dụ về một file XML:

<?xml version="1.0"?> <person gender="female"> <name>Chanh</name> <country>Viet Nam</country> <city>Ha Noi</city> <skills> <skill>JavaScrip</skill> <skill>React</skill> <skill>Python</skill> </skills> </person>
<?xml version="1.0"?> <person gender="female"> <name>Chanh</name> <country>Viet Nam</country> <city>Ha Noi</city> <skills> <skill>JavaScrip</skill> <skill>React</skill> <skill>Python</skill> </skills> </person>

Để biết thêm thông tin về cách đọc một file XML trong python, hãy tham khảo thêm về tài liệu về xml

import xml.etree.ElementTree as ET tree = ET.parse('./files/xml_example.xml') root = tree.getroot() print('Root tag:', root.tag) print('Attribute:', root.attrib) for child in root: print('field: ', child.tag) # output # Root tag: person # Attribute: {'gender': 'male'} # field: name # field: country # field: city # field: skills
import xml.etree.ElementTree as ET tree = ET.parse('./files/xml_example.xml') root = tree.getroot() print('Root tag:', root.tag) print('Attribute:', root.attrib) for child in root: print('field: ', child.tag) # output # Root tag: person # Attribute: {'gender': 'male'} # field: name # field: country # field: city # field: skills

Bài tập

  1. Viết một hàm đếm số dòng và số từ trong văn bản:
    a) Đọc tệp obama_speech.txt và đếm số dòng và số từ.
    b) Đọc tệp michelle_obama_speech.txt và đếm số dòng và số từ.
    c) Đọc tệp donald_speech.txt và đếm số dòng và số từ .
    d) Đọc tệp melina_trump_speech.txt và đếm số dòng và số từ.
  2. Đọc tệp dữ liệu country_data.json, tạo một hàm tìm 10 ngôn ngữ được nói nhiều nhất.
# Kết quả của bạn sẽ giống như thế này print(most_spoken_languages(filename='./data/countries_data.json', 10)) [(91, 'English'), (45, 'French'), (25, 'Arabic'), (24, 'Spanish'), (9, 'Russian'), (9, 'Portuguese'), (8, 'Dutch'), (7, 'German'), (5, 'Chinese'), (4, 'Swahili'), (4, 'Serbian')] # Kết quả của bạn sẽ giống như thế này print(most_spoken_languages(filename='./data/countries_data.json', 3)) [(91, 'English'), (45, 'French'), (25, 'Arabic')]
# Kết quả của bạn sẽ giống như thế này print(most_spoken_languages(filename='./data/countries_data.json', 10)) [(91, 'English'), (45, 'French'), (25, 'Arabic'), (24, 'Spanish'), (9, 'Russian'), (9, 'Portuguese'), (8, 'Dutch'), (7, 'German'), (5, 'Chinese'), (4, 'Swahili'), (4, 'Serbian')] # Kết quả của bạn sẽ giống như thế này print(most_spoken_languages(filename='./data/countries_data.json', 3)) [(91, 'English'), (45, 'French'), (25, 'Arabic')]
  1. Đọc tệp dữ liệu country_data.json, tạo một hàm để hiển thị một list 10 mười quốc gia đông dân nhất
# Kết quả của bạn sẽ giống như thế này print(most_populated_countries(filename='./data/countries_data.json', 10)) [ {'country': 'China', 'population': 1377422166}, {'country': 'India', 'population': 1295210000}, {'country': 'United States of America', 'population': 323947000}, {'country': 'Indonesia', 'population': 258705000}, {'country': 'Brazil', 'population': 206135893}, {'country': 'Pakistan', 'population': 194125062}, {'country': 'Nigeria', 'population': 186988000}, {'country': 'Bangladesh', 'population': 161006790}, {'country': 'Russian Federation', 'population': 146599183}, {'country': 'Japan', 'population': 126960000} ] # Kết quả của bạn sẽ giống như thế này print(most_populated_countries(filename='./data/countries_data.json', 3)) [ {'country': 'China', 'population': 1377422166}, {'country': 'India', 'population': 1295210000}, {'country': 'United States of America', 'population': 323947000} ]
# Kết quả của bạn sẽ giống như thế này print(most_populated_countries(filename='./data/countries_data.json', 10)) [ {'country': 'China', 'population': 1377422166}, {'country': 'India', 'population': 1295210000}, {'country': 'United States of America', 'population': 323947000}, {'country': 'Indonesia', 'population': 258705000}, {'country': 'Brazil', 'population': 206135893}, {'country': 'Pakistan', 'population': 194125062}, {'country': 'Nigeria', 'population': 186988000}, {'country': 'Bangladesh', 'population': 161006790}, {'country': 'Russian Federation', 'population': 146599183}, {'country': 'Japan', 'population': 126960000} ] # Kết quả của bạn sẽ giống như thế này print(most_populated_countries(filename='./data/countries_data.json', 3)) [ {'country': 'China', 'population': 1377422166}, {'country': 'India', 'population': 1295210000}, {'country': 'United States of America', 'population': 323947000} ]
  1. Hiển thị tất cả các địa chỉ email đến dưới dạng list từ tệp email_exchange_big.txt.
  2. Tìm những từ thông dụng nhất trong ngôn ngữ tiếng Anh. Tạo một hàm có tên find_most_common_wordsfind_most_common_words, nó sẽ nhận hai tham số - một chuỗi hoặc một tệp và một số nguyên dương, cho biết số lượng từ. Hàm của bạn sẽ trả về một mảng các bộ giá trị theo thứ tự giảm dần.
# Kết quả của bạn sẽ giống như thế này print(find_most_common_words('sample.txt', 10)) [(10, 'the'), (8, 'be'), (6, 'to'), (6, 'of'), (5, 'and'), (4, 'a'), (4, 'in'), (3, 'that'), (2, 'have'), (2, 'I')] # Kết quả của bạn sẽ giống như thế này print(find_most_common_words('sample.txt', 5)) [(10, 'the'), (8, 'be'), (6, 'to'), (6, 'of'), (5, 'and')]
# Kết quả của bạn sẽ giống như thế này print(find_most_common_words('sample.txt', 10)) [(10, 'the'), (8, 'be'), (6, 'to'), (6, 'of'), (5, 'and'), (4, 'a'), (4, 'in'), (3, 'that'), (2, 'have'), (2, 'I')] # Kết quả của bạn sẽ giống như thế này print(find_most_common_words('sample.txt', 5)) [(10, 'the'), (8, 'be'), (6, 'to'), (6, 'of'), (5, 'and')]
  1. Tạo một hàm find_most_frequent_wordsfind_most_frequent_words để tìm:
    a) Mười từ thường dùng nhất trong bài phát biểu của Obama.
    b) Mười từ thường dùng nhất trong bài phát biểu của Michelle.
    c) Mười từ thường dùng nhất trong bài phát biểu của Trump.
    d) Mười từ thường dùng nhất trong bài phát biểu của Melina.
  2. Viết một ứng dụng python để kiểm tra độ giống nhau giữa hai văn bản. Nó nhận một tệp hoặc một chuỗi làm tham số và nó sẽ đánh giá sự giống nhau của hai văn bản. Ví dụ, hãy kiểm tra sự giống nhau giữa bài phát biểu của Michelle và Melina. Bạn có thể sẽ viết một vài function như hàm làm sạch văn bản (clean_text), hàm hỗ trợ loại bỏ các từ (remove_support_words) và hàm cuối cùng để kiểm tra độ tương đồng (check_text_similarity). Xuất ra danh sách các từ nằm trong thư mục data của bạn.
  3. Tìm 10 từ được lặp lại nhiều nhất trong tệp romeo_and_juliet.txt.
  4. Đọc tệp tin hacker news csv và tìm hiểu:
    a) Đếm số dòng chứa python hoặc Python.
    b) Đếm số dòng chứa JavaScript, javascript hoặc Javascript.
    c) Đếm số dòng chứa Java và không phải JavaScript.