Python - Khi nào sử dụng tệp vs mở


138

Sự khác biệt giữa fileopentrong Python là gì? Khi nào tôi nên sử dụng cái nào? (Nói tôi ở 2.5)

Câu trả lời:


153

Bạn nên luôn luôn sử dụng open().

Như tài liệu nêu:

Khi mở tệp, tốt nhất nên sử dụng open () thay vì gọi trực tiếp hàm tạo này. tệp phù hợp hơn với kiểm tra loại (ví dụ: viết "isinstance (f, file)").

Ngoài ra, file() đã bị xóa kể từ Python 3.0.


23
Điều này gây khó chịu, vì tài liệu được sử dụng để nêu "Hàm tạo tệp () là mới trong Python 2.2. Chính tả trước đó, open (), được giữ lại để tương thích và là bí danh cho tệp ()." Vì tôi đã quyết định RTFM mười năm trước, và trở nên rất thích sự hợp nhất của các loại và các lớp, tôi không bao giờ sử dụng open () nữa. Hơn nữa, tôi vẫn cảm thấy rằng hàm tạo kiểu là cách rõ ràng hơn để trả về một tệp giống như đối tượng, được đặt bởi đường dẫn arg và hành xử theo yêu cầu trong chế độ arg. Tôi đặc biệt cảm thấy như vậy khi ý định rõ ràng của các nhà phát triển hồi đó là 2 giữ lại open4compat.
umeboshi

32

Hai lý do: Triết lý trăn "Phải có một cách để làm điều đó" và filesẽ biến mất.

filelà loại thực tế (sử dụng ví dụ như file('myfile.txt')gọi hàm tạo của nó). openlà một chức năng của nhà máy sẽ trả về một đối tượng tập tin.

Trong python 3.0 filesẽ chuyển từ việc tích hợp sang được triển khai bởi nhiều lớp trong iothư viện (hơi giống với Java với các trình đọc được đệm, v.v.)


3
Hai lý do để làm gì?
Matt

19

file()là một loại, giống như một int hoặc một danh sách. open()là một chức năng để mở tập tin và sẽ trả về một fileđối tượng.

Đây là một ví dụ về thời điểm bạn nên sử dụng mở:

f = open(filename, 'r')
for line in f:
    process(line)
f.close()

Đây là một ví dụ về thời điểm bạn nên sử dụng tệp:

class LoggingFile(file):
    def write(self, data):
        sys.stderr.write("Wrote %d bytes\n" % len(data))
        super(LoggingFile, self).write(data)

Như bạn có thể thấy, có một lý do chính đáng để cả hai tồn tại và trường hợp sử dụng rõ ràng cho cả hai.


5
Nói chung, các tập tin nên được mở với withtuyên bố. with open(filename, 'r') as f: \ for line in f: \ process(line). Điều này tránh sự gần gũi rõ ràng. Python 2.6 trở lên hỗ trợ withcâu lệnh. Trong Python 2.5, bạn phải thêm from __future__ import with_statementvào đầu mã của mình.
IceArdor

Không phải bạn vừa xác định lại tên tích hợp trong ví dụ thứ hai sao?
tinh

1
@planetp, ví dụ thứ hai chỉ kế thừa từ lớp tệp. Tôi cho rằng thật kỳ lạ khi nó ở dạng chữ thường, nhưng đó là như vậy với các loại dựng sẵn cơ bản (ví dụ: object, str, list, ...)
yoniLavi

1
Trong Python 2.5, filelớp được trang bị các phương thức đặc biệt được gọi tự động mỗi khi tệp được mở thông qua withcâu lệnh. Các phương pháp đặc biệt này đảm bảo rằng tệp được mở và đóng đúng cách và an toàn.
Mausy5043

7

Về mặt chức năng, hai cái này giống nhau; Dù sao cũng opensẽ gọi file, vì vậy hiện tại sự khác biệt là vấn đề về phong cách. Các tài liệu Python khuyên bạn nên sử dụng open.

Khi mở tệp, tốt nhất nên sử dụng open () thay vì gọi trực tiếp hàm tạo tệp.

Lý do là trong các phiên bản trong tương lai, chúng không được đảm bảo giống nhau ( opensẽ trở thành chức năng của nhà máy, trả về các đối tượng thuộc các loại khác nhau tùy thuộc vào đường dẫn mà nó mở).


2
open đã là một chức năng của nhà máy, vì vậy có sự khác biệt về chức năng (ví dụ: thừa kế, isinstance (), v.v.)
Brian

4

Chỉ bao giờ sử dụng open () để mở tệp. file () thực sự đang bị xóa trong 3.0 và hiện tại nó không dùng nữa. Họ đã có một mối quan hệ kỳ lạ, nhưng tập tin () đang diễn ra, vì vậy không cần phải lo lắng nữa.

Sau đây là từ các tài liệu Python 2.6. [khung công cụ] được thêm bởi tôi.

Khi mở tệp, tốt nhất nên sử dụng open () thay vì gọi trực tiếp hàm tạo [file ()] này. tệp phù hợp hơn với kiểm tra loại (ví dụ: viết isinstance (f, file)


2

Theo ông Van Rossum, mặc dù open () hiện là bí danh cho tệp () bạn nên sử dụng open () vì điều này có thể thay đổi trong tương lai.

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.