Trong Python, bạn mở một tệp bằng cách sử dụng hàm open[]
tích hợp và chuyển cho nó đường dẫn đến tệp bạn muốn mở. Theo mặc định, các tệp được mở ở dạng chỉ đọc
Đây là một ví dụ rất cơ bản về việc mở và đọc một tệp là thư mục hiện tại
f = open['myfile.txt']
contents = f.read[]
print[contents]
f.read[]
chỉ đọc toàn bộ tệp dưới dạng một chuỗi thành một biến. Vì vậy, điều này sẽ chỉ in toàn bộ nội dung của tệp
Ngoài ra, bạn có thể muốn đọc tệp thành một danh sách, mỗi lần một dòng. Bạn có thể làm điều đó với phương pháp
f = open['myfile.txt']
file_as_list = f.readlines[]
for line in file_as_list:
print[line]
0f = open['myfile.txt']
file_as_list = f.readlines[]
for line in file_as_list:
print[line]
Kết quả có thể làm bạn ngạc nhiên mặc dù. Khi được in, mỗi dòng sẽ được theo sau bởi hai ký tự xuống dòng. Đó là bởi vì
f = open['myfile.txt']
file_as_list = f.readlines[]
for line in file_as_list:
print[line]
0 không tách ký tự xuống dòng khi tách nội dung thành danh sách. Mỗi mục danh sách sẽ kết thúc bằng ký tự xuống dòng. Điều đó chiếm một trong những ký tự dòng mới. Theo mặc định, ký tự xuống dòng khác xuất hiện ở cuối mỗi cuộc gọi đến f = open['myfile.txt']
file_as_list = f.readlines[]
for line in file_as_list:
print[line]
2 Điều này có liên quan đến lỗi 18291. Có lẽ một số người sẽ ngạc nhiên rằng str. splitlines[] phân chia thành nhiều thứ khác ngoài các ký tự xuống dòng [\n] và ký tự xuống dòng [\r]. Điều đó không giống như đối tượng str trong Python 2. Xem tài liệu cho. Bởi vì mô-đun codec sử dụng str. splitlines nội bộ, bạn sẽ có hành vi chia dòng khác nhau khi bạn sử dụng codec. getreader[] so với sử dụng open[] với tệp chế độ văn bản
Tôi không thấy ý nghĩa của việc các đường phân tách [] coi tất cả các ký tự điều khiển bổ sung này là các đường phân tách. Nếu tôi xem xét việc sử dụng splitlines[] trong stdlib, có vẻ như mọi người thường muốn hành vi phân tách giống như những gì tệp
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
5 thực hiện. Tôi sẽ không ngạc nhiên nếu có lỗi thực sự, một số lỗi liên quan đến bảo mật, do hành vi nàySau khi thực hiện một số thao tác đào, có vẻ như hành vi này quay trở lại khi loại
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
6 như được giới thiệu trong Python 2. Tôi nghi ngờ khi mã được chuyển đổi từ 2 sang 3, splitlines[] đã thay đổi từ hoạt động trên byte sang hoạt động trên chuỗi unicode. Và, tôi cá là mọi người đã không nhận ra sự khác biệt trong hành vi nàyIMHO, lý tưởng nhất là trường hợp
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
7Tôi đang đăng ở đây vì tôi không biết liệu đây có phải là điều chúng ta có thể thay đổi hay không, vì đó có thể là hành vi mà mọi người đang dựa vào
Có một số lỗi trong trình theo dõi vấn đề liên quan đến điều này, một số mở, một số đóng. Tôi đã tìm thấy lỗi 22232 có vẻ phù hợp nhất [str. các đường phân tách chia tách trên các ký tự không phải\r\n]. Bây giờ tôi không chắc mình có nên đưa cuộc thảo luận vào đây không, có lẽ tôi nên giữ nó bên trong trình theo dõi vấn đề
Marc-Andre Lemburg đã nhận xét về vấn đề này và là -1 khi thay đổi str. hành vi splitlines và cũng không nghĩ rằng
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
8 nên được thay đổi. Tôi có thể thấy lập luận của anh ấy từ quan điểm thuần khiết của Unicode. Tuy nhiên, đối với tôi, có vẻ như hành vi này tạo ra nhiều lỗi hơn là hữu ích. Đặt tên unicode. phương pháp splitlines giống như str. splitlines là một sai lầm, IMHONếu tôi xem xét việc sử dụng
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
9 trong thư viện chuẩn Python và trong 50 gói PyPi hàng đầu, gần như mọi trường hợp dường như mong đợi được phân tách trên '\r' và '\n' hoặc chỉ trên '\n'. Trong hầu hết các trường hợp, mã này khớp với mã Python 2 và thường thì giá trị được chia là argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
0. Tôi chưa tìm thấy bất kỳ trường hợp nào rõ ràng là mong muốn tách kiểu Unicode. Vì vậy, đó là lý do tại sao tôi cảm thấy Marc-Andre đang tranh luận về sự thuần khiết hơn là tính thực tếThêm một phương pháp mới như
argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
1 có thể là giải pháp tốt nhất. Nếu chúng tôi làm như vậy, tôi nghĩ nó chỉ nên tách trên \and, vì vậy nó khớp với argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
2 trên các đối tượng tệp. Chúng ta nên cung cấp cho nó một từ khóa argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
3 để việc sửa các cuộc gọi của argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
4 trở nên dễ dàng. Sau đó, chúng tôi phải kiểm tra tất cả các cách sử dụng của argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
4 và hầu hết chúng cần được thay đổi thành argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
1Tôi muốn đối tượng người đọc
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
8 nhận tham số từ khóa argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
8 và để nó hoạt động giống như phiên bản argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
9. Sau đó, các mô-đun như linecache.py
113: [line+'\n' for line in data.splitlines[]], fullname
0 phải có cách để kiểm tra xem linecache.py
113: [line+'\n' for line in data.splitlines[]], fullname
1 đã được sử dụng chưa và cảnh báo nếu chưa. Đối với tôi, có vẻ như có nhiều lỗi liên quan đến hành vi phân tách Unicode này. Bắt đầu đặt các ký tự \v trong tiêu đề giao thức, trường tệp CSV, v.v. và bạn sẽ thấy nhiều hành vi không mong muốnĐây là một phân tích nhanh về việc sử dụng
linecache.py
113: [line+'\n' for line in data.splitlines[]], fullname
2 bên trong stdiib. Không rõ mục đích là gì [hoặc thậm chí nếu đôi khi dữ liệu là argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
0 hoặc linecache.py
113: [line+'\n' for line in data.splitlines[]], fullname
4]. Vì vậy, hãy coi phân tích của tôi như muối bỏ bể khi tôi đã thực hiện nó một cách nhanh chóngcodecs.py
509: lines = newchars.splitlines[keepends=True]
551: line = line.splitlines[keepends=False][0]
568: lines = line.splitlines[keepends=True]
584: line = line.splitlines[keepends=False][0]
587: line0withoutend = lines[0].splitlines[keepends=False][0]
600: line = line.splitlines[keepends=False][0]
619: return data.splitlines[keepends]
822: return data.splitlines[keepends=True]
Marc-Andre gợi ý rằng codec nên chia dòng theo Unicode
ISNEWLINE quy tắc và không được khớp với tệp. readlines[] cho tệp văn bản. tôi nghĩ
nếu không thì hãy để lại trường hợp này. Ở mức tối thiểu, tôi nghĩ getreader[] nên
nhận một tùy chọn
argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
8 để làm cho nó khớp với những gì open[] làmnntplib.py
896: f = f.splitlines[]
Trong trường hợp này,
linecache.py
113: [line+'\n' for line in data.splitlines[]], fullname
6 là byte nên điều này có thể ổn. Không chắc chắn tách trên băng \rđược rồi
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
Chỉ tách trên '\n'
argparse.py
655: return ''.join[indent + line for line in text.splitlines[keepends=True]]
666: return text.splitlines[]
2047: for arg_line in args_file.read[].splitlines[]:
Chỉ tách trên '\n'
linecache.py
113: [line+'\n' for line in data.splitlines[]], fullname
Chỉ tách trên '\n'
pprint.py
250: lines = object.splitlines[True]
Chỉ tách trên '\n'
difflib.py
785: .. '''.splitlines[keepends=True]
794: .. '''.splitlines[keepends=True]
880: >>> print[''.join[Differ[].compare['one\ntwo\nthree\n'.splitlines[True],
881: .. 'ore\ntree\nemu\n'.splitlines[True]]],
1247: >>> print[''.join[context_diff['one\ntwo\nthree\nfour\n'.splitlines[True],
1248: .. 'zero\none\ntree\nfour\n'.splitlines[True], 'Original', 'Current']],
1366: >>> diff = ndiff['one\ntwo\nthree\n'.splitlines[keepends=True],
1367: .. 'ore\ntree\nemu\n'.splitlines[keepends=True]]
2070: >>> diff = ndiff['one\ntwo\nthree\n'.splitlines[keepends=True],
2071: .. 'ore\ntree\nemu\n'.splitlines[keepends=True]]
Tách trên '\n' hoặc '\r'?
pydoc.py
288: result = module.__doc__.splitlines[][0] if module.__doc__ else None
2155: desc = module.__doc__.splitlines[][0] if module.__doc__ else ''
Chỉ tách trên '\n'
smtpd.py
709: lines = data.splitlines[]
Tách trên '\r' hoặc '\n'?
site.py
180: for line in record.splitlines[]:
Chỉ tách trên '\n'
nntplib.py
896: f = f.splitlines[]
0Tách theo Unicode ISNEWLINE?
cũng tốt
nntplib.py
896: f = f.splitlines[]
1Được rồi, đây là byte
nntplib.py
896: f = f.splitlines[]
2Chỉ tách trên '\n'?
nntplib.py
896: f = f.splitlines[]
3Chỉ tách trên '\n'?
nntplib.py
896: f = f.splitlines[]
4Chỉ tách trên '\n'?
nntplib.py
896: f = f.splitlines[]
5Chỉ tách trên '\n'?
nntplib.py
896: f = f.splitlines[]
6Chỉ tách trên '\n'?
nntplib.py
896: f = f.splitlines[]
7Chỉ tách trên '\n'?
nntplib.py
896: f = f.splitlines[]
8Chỉ tách trên '\n'
nntplib.py
896: f = f.splitlines[]
9Chỉ tách trên '\n'
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
0Tách trên '\n' hoặc '\r'?
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
1Tách trên '\n' hoặc '\r'?
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
2Tách trên '\n'
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
3Tách trên '\n'
doctest.py
1413: return example.source.splitlines[keepends=True]
1676: want_lines = want.splitlines[keepends=True]
1677: got_lines = got.splitlines[keepends=True]
4Tách trên '\n'
Tôi không thấy cách hành vi hiện tại là một mặc định tốt. Tôi có thể hiểu nếu chúng tôi không thể thay đổi nó do tính tương thích ngược. Tôi có thể lập luận rằng chúng ta sẽ làm nhiều điều tốt hơn là làm hại bằng cách thay đổi nó
Chúng tôi đã có cuộc thảo luận về trình theo dõi lỗi
Tóm lại tình hình là thế này
Khi Unicode được thêm vào, tôi đã tập trung vào việc đưa ra các quyết định thiết kế phù hợp từ góc độ Unicode. Unicode xác định nhiều ngắt dòng hơn ASCII, vì vậy chúng tôi phải bao gồm tất cả chúng để phù hợp với tiêu chuẩn, giống như Unicode xác định nhiều ký tự hơn có thể được hiểu là chữ số hoặc thậm chí là số nguyên và các phương thức tương ứng, chẳng hạn như. isdigit[] đã được mở rộng. Điều này là cần thiết, vì đối tượng Unicode trong Python được cho là đại diện cho Unicode theo tiêu chuẩn
Bây giờ, khi Python 3 chuyển sang sử dụng Unicode thay vì byte cho “str”, chúng tôi đã nhận được ngữ nghĩa Unicode, nhưng không thực sự thông qua stdlib [hoặc mã khác] được viết với ngữ nghĩa ASCII trong một số phần. Trong một số trường hợp, điều này hữu ích, trong những trường hợp khác thì không, vì giờ đây Python sẽ nhận ra nhiều "ký tự" dưới dạng ngắt dòng hoặc chữ số hơn so với kế hoạch ban đầu của quy trình tương ứng. tác giả mã
Sau ngần ấy thời gian, tôi không nghĩ rằng chúng ta có thể thay đổi ngữ nghĩa một cách triệt để nữa và đơn giản là phải chấp nhận rằng chúng ta đã không xem xét kỹ các hàm ý khi chuyển từ str=bytes sang str=unicode
Nhìn chung, tôi không nghĩ có nhiều trường hợp ngữ nghĩa Unicode gây ra vấn đề trong cuộc sống thực. Một vài ký tự cuối dòng bổ sung rất hiếm khi được sử dụng trong thực tế và rất có thể sẽ chỉ ra các vấn đề với dữ liệu, thay vì các vấn đề với mã, trong những trường hợp bạn không muốn các điểm mã mới được hiểu là ngắt dòng
Nếu bạn thực sự đang làm việc với văn bản Unicode chứ không phải với văn bản ASCII mà bạn tình cờ nhận được dưới dạng Uncode str, thì bạn thực sự muốn các ngắt dòng này, vì đó là những gì Unicode định nghĩa và những gì tác giả của văn bản sẽ sử dụng làm cơ sở để viết văn bản. chữ. Về mặt này, hành động của. splitlines[] là chính xác. Nó chỉ không đúng đối với các tiêu chuẩn chỉ bắt buộc các ký tự ngắt dòng ASCII
Tôi nghĩ đối với mã chắc chắn chỉ có thể bị hỏng trên các dòng mới ASCII, chúng ta nên tạo một phương thức mới [e. g. . asciilines[]] hoặc thêm một tham số vào. splitlines[] hạn chế tập hợp các ký tự được chia thành các ký tự ASCII mà chúng tôi đã có trong Python 2