Cách dễ nhất để đọc / ghi nội dung của tệp bằng Python


82

Trong Ruby, bạn có thể đọc từ một tệp bằng cách sử dụng s = File.read(filename). Câu ngắn nhất và rõ ràng nhất mà tôi biết trong Python là

with open(filename) as f:
    s = f.read()

Có cách nào khác để làm điều đó giúp nó ngắn hơn (tốt nhất là một dòng) và dễ đọc hơn không?

Lưu ý: ban đầu tôi diễn đạt câu hỏi là "thực hiện điều này trong một dòng mã". Như đã chỉ ra bởi S.Lott, ngắn hơn không cần thiết có nghĩa là dễ đọc hơn. Vì vậy, tôi nói lại câu hỏi của mình chỉ để làm rõ ý tôi. Tôi nghĩ rằng mã Ruby tốt hơn và dễ đọc hơn không nhất thiết vì nó một dòng so với hai dòng (mặc dù điều đó cũng quan trọng), mà còn bởi vì nó là một phương thức lớp đối lập với một phương thức thể hiện, điều này không đặt ra câu hỏi về việc ai đóng tệp, làm thế nào để đảm bảo nó được đóng ngay cả khi một ngoại lệ được đưa ra, v.v. Như đã chỉ ra trong các câu trả lời bên dưới, bạn có thể dựa vào GC để đóng tệp của mình (do đó làm cho tệp này trở thành một lớp lót), nhưng điều đó làm cho mã trở nên tồi tệ hơn mặc dù nó ngắn hơn. Không chỉ bởi không thể di chuyển mà còn làm cho nó không rõ ràng.


7
Tạo chức năng của riêng bạn. Sau đó, bạn có thể sử dụng nó để lấy nội dung. Cuộc gọi sẽ là một dòng.
Felix Kling

1
Bạn chỉ cần tò mò, câu lệnh Ruby có đóng tệp không?
dheerosaur

8
-1: Không ai thắng ở môn gôn mã.
S.Lott

3
Câu hỏi của tôi có ý nghĩa đối với tôi. Tôi đang cố gắng tìm cách tốt hơn để viết hai dòng này (4 dòng trước withcâu lệnh trong 2.5). Có thể có một cách, có thể không có. Tôi luôn có thể cố gắng tìm hiểu, phải không? Nếu bạn không thích nó, hãy từ chối và tiếp tục. :)
ibz

1
Lợi ích của File.readlines("filename")nó là nó đọc nội dung của một tệp được đặt tên của nó. Không có xử lý tệp, bộ mô tả hoặc đối tượng ở bất kỳ đâu trong bằng chứng. Tất cả các "tương đương" Python mà tôi đã thấy đều bao gồm mở / đóng rõ ràng (hoặc tệ hơn là mở ngầm yêu cầu đóng rõ ràng).
Mark Reed

Câu trả lời:


11

Nếu bạn muốn sử dụng các thư viện, hãy thử cài đặt đường dẫn phân nhánh (với easy_install hoặc pip).

Sau đó, bạn có thể làm:

from path import path
s = path(filename).bytes()

Thư viện này khá mới, nhưng nó là một nhánh của thư viện đã trôi nổi trên Python trong nhiều năm và đã được sử dụng khá nhiều. Kể từ khi tôi tìm thấy thư viện này nhiều năm trước, tôi rất ít khi sử dụng os.pathhoặc open()bất kỳ thứ gì khác.


Trông giống như một thư viện đẹp. Tôi sẽ không cài đặt nó chỉ vì điều này, nhưng tôi sẽ ghi nhớ nó.
ibz

1
Tôi không hiểu tại sao đây lại là câu trả lời được chấp nhận vì nó là một vụ hack hoàn toàn!
nikolay

Forked-path v0.2.3 được cài đặt bởi pip 18.6 trên Windows không tương thích với Python 3.6.4. Có vẻ như định dạng được sử dụng cho hằng số bát phân (ví dụ: 0777thay vì 0o0777) không được phiên bản python hiện tại của tôi hỗ trợ.
Christoffer Soop

+1 cho câu trả lời của Eyal Levin . Nếu pathlib hoặc pathlib2 đã tồn tại khi tôi trả lời câu hỏi này 8 năm trước, tôi sẽ đề cập đến chúng hơn là fork-path. Tôi đã không sử dụng đường rẽ nhánh trong nhiều năm.
snapshoe

149
with open('x.py') as f: s = f.read()

*** cười toe toét ***


1
Chỉ không có lý do gì để không viết nó như OP ban đầu. Ý định đã rõ ràng.
Mark Tolonen

43

Điều này tương tự như trên nhưng không xử lý lỗi:

s = open(filename, 'r').read()

21
Không thực sự, của bạn để lại tệp mở.
ibz

3
Việc triển khai CPython không đóng tệp khi số lượng tham chiếu bằng không, nhưng đó là chi tiết triển khai không nên dựa vào.
Mark Tolonen

1
Điều này không xử lý các lỗi; một ngoại lệ sẽ được ném như bình thường. Điều này không "để tệp mở", nhưng những gì nó có thể làm là khiến việc đóng tệp bị trì hoãn tùy thuộc vào việc triển khai GC. Đó có thể là một vấn đề (khóa trong Windows, và ví dụ: giới hạn FD nếu lặp qua nhiều tệp), nhưng điều đó rất khác với việc để tệp mở (ví dụ: rò rỉ tệp).
Glenn Maynard

11
Nếu mục tiêu thiết kế của bạn là "một dòng mã", bạn đã hít quá nhiều Perl và bạn cần lên lịch cho một số thời gian không tẩy não nghiêm trọng.
Glenn Maynard

6
Không, điều này không khó hiểu chút nào.
Glenn Maynard

36

Sử dụng pathlib .

Python 3.5 trở lên:

from pathlib import Path
contents = Path(file_path).read_text()

Đối với các phiên bản Python thấp hơn, hãy sử dụng pathlib2 :

$ pip install pathlib2

Sau đó

from pathlib2 import Path
contents = Path(file_path).read_text()

Viết cũng dễ dàng:

Path(file_path).write_text('my text')

18
contents = open(filename).read()

9
Và khi nào bạn đóng tệp?
ibz

1
@ionut bizau - open(...)Tôi nghĩ khi trả về là rác được thu gom. Ai đó sửa cho tôi nếu tôi sai.
detly

1
Đây là cách ngắn nhất để làm điều đó. tôi không biết tại sao nó không có phiếu bầu.
Pritesh Acharya

10

Đây không phải là Perl; bạn không muốn bắt buộc phải khớp nhiều dòng mã vào một dòng duy nhất. Viết một hàm, sau đó gọi hàm cần một dòng mã.

def read_file(fn):
    """
    >>> import os
    >>> fn = "/tmp/testfile.%i" % os.getpid()
    >>> open(fn, "w+").write("testing")
    >>> read_file(fn)
    'testing'
    >>> os.unlink(fn)
    >>> read_file("/nonexistant")
    Traceback (most recent call last):
        ...
    IOError: [Errno 2] No such file or directory: '/nonexistant'
    """
    with open(fn) as f:
        return f.read()

if __name__ == "__main__":
    import doctest
    doctest.testmod()

5

Chậm, xấu, nền tảng cụ thể ... nhưng một lớp lót ;-)

import subprocess

contents = subprocess.Popen('cat %s' % filename, shell = True, stdout = subprocess.PIPE).communicate()[0]

3
aaaaaaaaaaaaaa! (dư thừa 'một là để giới hạn đáp ứng tối thiểu char)
Peter Gibson

5
Chắc chắn phù hợp với tinh thần của câu hỏi ... việc sử dụng Python để làm cho nó giống Bash không tệ hơn là làm cho nó giống Ruby hoặc Perl.
detly

3

Đơn giản như thế:

    f=open('myfile.txt')
    s=f.read()
    f.close()

Và làm bất cứ điều gì bạn muốn với nội dung "s"


-1
contents = open(filename)

Điều này cung cấp cho bạn trình tạo, vì vậy bạn phải lưu ở đâu đó các giá trị, hoặc

contents = [line for line in open(filename)]

Điều này không thực hiện được việc lưu vào danh sách đóng rõ ràng sau đó là không thể (ít nhất là với kiến ​​thức của tôi về Python).


1
và có nội dung = '' .join (dòng cho dòng trong mở (filename)) bạn có các nội dung tập tin gốc ...
eumiro

Việc sử dụng tệp làm trình lặp không đóng tệp một cách xác định (giống như withvậy). Không thể, vì sau khi quá trình lặp kết thúc, việc tìm kiếm tệp và bắt đầu đọc lại vẫn hợp lệ, điều này sẽ không hoạt động nếu quá trình lặp đóng tệp.
Glenn Maynard

@Glenn Nhưng nếu bạn sử dụng trình tạo trong danh sách hiểu như ví dụ của tôi, bạn thậm chí không thể đóng nó vì nó không có tên.
Tony Veijalainen

"Không đóng được" không giống như "không cần đóng".
Glenn Maynard

Có thể như vậy nhưng bạn, tôi sẽ không biết cách truy cập tệp xử lý đó từ bên trong danh sách. Có thể là lệnh 'đã hoàn thành tất cả tệp i / o, đóng tất cả chương trình đã mở tệp' bằng Python? Hoặc có thể gc rõ ràng cho các đối tượng tệp sẽ là đủ? Xử lý tệp mặc dù nằm ngoài phạm vi vì khả năng hiểu danh sách là phạm vi riêng biệt.
Tony Veijalainen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.