Tại sao tôi không thể sử dụng một chuỗi cho một dòng mới trong write () nhưng tôi có thể sử dụng nó trong writelines ()?
Ý tưởng là như sau: nếu bạn muốn viết một chuỗi đơn, bạn có thể làm điều này với write()
. Nếu bạn có một chuỗi các chuỗi, bạn có thể viết tất cả chúng bằng cách sử dụngwritelines()
.
write(arg)
mong đợi một chuỗi làm đối số và ghi nó vào tệp. Nếu bạn cung cấp danh sách các chuỗi, nó sẽ tạo ra một ngoại lệ (nhân tiện, hiển thị lỗi cho chúng tôi!).
writelines(arg)
mong đợi một đối số có thể lặp lại (một đối tượng có thể lặp có thể là một bộ, một danh sách, một chuỗi hoặc một trình lặp theo nghĩa chung nhất). Mỗi mục chứa trong trình vòng lặp được mong đợi là một chuỗi. Một bộ dây là những gì bạn đã cung cấp, vì vậy mọi thứ đã hoạt động.
Bản chất của (các) chuỗi không quan trọng đối với cả hai hàm, tức là chúng chỉ ghi vào tệp bất cứ thứ gì bạn cung cấp cho chúng. Phần thú vị là nó writelines()
không tự thêm các ký tự dòng mới, vì vậy tên phương thức thực sự có thể khá khó hiểu. Nó thực sự hoạt động giống như một phương thức tưởng tượng được gọi write_all_of_these_strings(sequence)
.
Sau đây là một cách thành ngữ trong Python để ghi danh sách các chuỗi vào một tệp trong khi giữ mỗi chuỗi ở dòng riêng của nó:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.write('\n'.join(lines))
Thao tác này sẽ giúp bạn đóng tệp. Cấu trúc '\n'.join(lines)
nối (kết nối) các chuỗi trong danh sách lines
và sử dụng ký tự '\ n' làm keo dán. Nó hiệu quả hơn việc sử dụng+
toán tử.
Bắt đầu từ cùng một lines
trình tự, kết thúc với cùng một đầu ra, nhưng sử dụng writelines()
:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.writelines("%s\n" % l for l in lines)
Điều này sử dụng một biểu thức trình tạo và tự động tạo các chuỗi kết thúc bằng dòng mới. writelines()
lặp lại chuỗi chuỗi này và ghi mọi mục.
Chỉnh sửa: Một điểm khác mà bạn cần lưu ý:
write()
và readlines()
tồn tại trước khi writelines()
được giới thiệu. writelines()
được giới thiệu sau đó như một bản sao của readlines()
, để người ta có thể dễ dàng ghi nội dung tệp vừa được đọc qua readlines()
:
outfile.writelines(infile.readlines())
Thực sự, đây là lý do chính tại sao writelines
có một cái tên khó hiểu như vậy. Ngoài ra, ngày nay, chúng tôi không thực sự muốn sử dụng phương pháp này nữa. readlines()
đọc toàn bộ tệp vào bộ nhớ của máy trước khi writelines()
bắt đầu ghi dữ liệu. Trước hết, điều này có thể lãng phí thời gian. Tại sao không bắt đầu viết các phần của dữ liệu trong khi đọc các phần khác? Nhưng, quan trọng nhất, cách tiếp cận này có thể rất tốn bộ nhớ. Trong một trường hợp cực đoan, khi tệp đầu vào lớn hơn bộ nhớ của máy bạn, phương pháp này thậm chí sẽ không hoạt động. Giải pháp cho vấn đề này là chỉ sử dụng các trình vòng lặp. Một ví dụ hoạt động:
with open('inputfile') as infile:
with open('outputfile') as outfile:
for line in infile:
outfile.write(line)
Điều này đọc từng dòng tệp đầu vào. Ngay sau khi một dòng được đọc, dòng này được ghi vào tệp đầu ra. Nói một cách giản lược, luôn chỉ có một dòng duy nhất trong bộ nhớ (so với toàn bộ nội dung tệp nằm trong bộ nhớ trong trường hợp của phương pháp readlines / writelines).
lines
không phải là một chuỗi trong ví dụ của bạn. Nó là một tuple bao gồm sáu dây.