2016-12-06 14 views
7

Về cú pháp trong PythonPython open() vs .close()

Tại sao chúng ta sử dụng open("file") để mở nhưng không "file".close() để đóng nó?
Tại sao không phải là "file".open() hoặc nghịch đảo close("file")?

+1

Đó là một điều phong cách. Các hàm làm việc với một đối tượng thường là các phương thức của đối tượng đó, nhưng bạn cần một cách tạo đối tượng ở vị trí đầu tiên ... –

+2

'" tệp ".open()' * có vẻ sai với tôi - không phải tất cả các chuỗi đều là các tệp hợp lệ để mở, do đó, có 'str.open()' có vẻ như thiết kế kém, trong khi tất cả các chuỗi có thể là 'split()', v.v. – Aurora0001

+1

Nó không phải là tệp "." .đóng() ', do đó," tệp " .open() 'sẽ không khớp. Tôi cho rằng nó dễ dàng có thể là 'close (file_object)'. – user2357112

Trả lời

1

Chỉ hơi kém mới hơn bạn nhưng tôi sẽ cung cấp cho cái này một đi, về cơ bản mở và đóng là hành động khá khác nhau trong một ngôn ngữ như python. Khi bạn đang mở tệp, những gì bạn đang thực sự đang tạo ra một đối tượng được làm việc bên trong ứng dụng của bạn đại diện cho tệp, do đó bạn tạo nó với một hàm thông báo cho hệ điều hành rằng tệp đã được mở và tạo một đối tượng mà python có thể sử dụng để đọc và ghi vào tệp. Khi đến lúc đóng tệp, những gì về cơ bản cần được thực hiện là cho ứng dụng của bạn thông báo cho hệ điều hành rằng nó được thực hiện với tệp và vứt bỏ đối tượng đại diện cho bộ nhớ fro bộ nhớ, và cách dễ nhất để làm điều đó là một phương pháp trên chính đối tượng đó. Cũng lưu ý rằng cú pháp như "file".open sẽ yêu cầu loại chuỗi để bao gồm các phương thức mở tệp, đó là một thiết kế rất lạ và yêu cầu nhiều phần mở rộng trên loại chuỗi cho bất kỳ thứ gì khác bạn muốn triển khai với cú pháp đó. close(file) sẽ có ý nghĩa hơn một chút nhưng vẫn là cách giải phóng đối tượng/cho phép hệ điều hành biết tệp không còn mở nữa và bạn sẽ chuyển một biến số file đại diện cho đối tượng được tạo khi bạn mở tệp thay vì chuỗi trỏ đến đường dẫn của tệp.

+1

Tôi có một vài chỉnh sửa mà tôi muốn giải thích: Chức năng 'mở' không đọc tệp của bạn vào bộ nhớ. 'read' và' readlines' làm điều đó. Ngoài ra, Không nhất thiết phải "khóa" trên bất kỳ tệp nào bạn mở. Nó phụ thuộc vào cách hệ điều hành xử lý các tham chiếu tệp mở. Tôi hiểu ý bạn là gì, nhưng tôi sẽ tránh sử dụng từ "khóa". – skrrgwasme

+0

Cảm ơn bạn! MS nền của tôi đã được hiển thị thông qua đó và tôi quên đi sự khác biệt trong cách một số hệ điều hành xử lý mở xử lý tập tin. thực sự đánh giá cao việc làm rõ và tôi đã cập nhật câu trả lời của mình. –

8

Đó là vì open() là một hàm và .close() là một phương pháp đối tượng. "file".open() không có ý nghĩa, bởi vì bạn ngụ ý rằng hàm open() thực sự là một lớp hoặc phương pháp thể hiện của chuỗi "file". Không phải tất cả các chuỗi đều là các tệp hoặc thiết bị hợp lệ được mở, do đó, cách trình thông dịch được cho là xử lý "not a file-like device".open() sẽ không rõ ràng. Chúng tôi không sử dụng "file".close() vì lý do tương tự.

close("file") sẽ yêu cầu tra cứu tên tệp, sau đó tìm kiếm khác để xem liệu có xử lý tệp hay không, thuộc sở hữu của quy trình hiện tại, được đính kèm với tệp đó. Điều đó sẽ rất không hiệu quả và có thể có những cạm bẫy ẩn khiến nó không đáng tin cậy (ví dụ, nếu nó không phải là một tập tin, mà là một thiết bị TTY thay thế?). Nó nhanh hơn và đơn giản hơn nhiều để chỉ giữ một tham chiếu đến tệp hoặc thiết bị đã mở và đóng tệp thông qua tham chiếu đó (còn được gọi là xử lý).

Nhiều ngôn ngữ áp dụng cách này:

f = open("file") # open a file and return a file object or handle 
# stuff... 
close(f)   # close the file, using the file handle or object as a reference 

này trông giống như close("file") xây dựng của bạn, nhưng đừng để bị lừa: nó đóng tập tin thông qua một tài liệu tham khảo trực tiếp với nó, không phải là tên tập tin như lưu trữ trong một chuỗi.

Các nhà phát triển Python đã chọn để làm điều tương tự, nhưng có vẻ khác nhau bởi vì họ đã thực hiện nó với một cách tiếp cận hướng đối tượng thay thế. Một phần lý do cho điều này là các đối tượng tệp Python have a lot of methods có sẵn cho chúng, chẳng hạn như read(), flush(), seek(), v.v. Nếu chúng tôi sử dụng close(f), thì chúng tôi sẽ phải thay đổi tất cả phần còn lại của các phương pháp đối tượng tệp chức năng, hoặc để cho nó là một chức năng ngẫu nhiên mà cư xử khác nhau từ phần còn lại không có lý do chính đáng.

TL; DR
Thiết kế của open()file.close() là phù hợp với hiệu trưởng OOP và thực hành tài liệu tham khảo tập tin tốt.open() là một chức năng giống như nhà máy, tạo ra các đối tượng tham chiếu tệp hoặc các thiết bị khác. Khi đối tượng được tạo ra, thì tất cả các hoạt động khác trên đối tượng đó được thực hiện thông qua các phương thức lớp hoặc thể hiện.

1

Thông thường bạn không nên sử dụng "file".close() một cách rõ ràng nhưng sử dụng open(file) làm trình quản lý ngữ cảnh để xử lý tệp cũng bị đóng nếu có ngoại lệ xảy ra. Kết thúc vấn đề :-)

Nhưng thực sự trả lời câu hỏi của bạn, giả sử lý do là open hỗ trợ nhiều tùy chọn và lớp trả về khác nhau tùy thuộc vào các tùy chọn này (xem thêm io module). Vì vậy, nó sẽ đơn giản là phức tạp hơn nhiều cho người dùng cuối để nhớ lớp nào anh ta muốn và sau đó sử dụng "class".open với chính lớp đó. Lưu ý bạn cũng có thể vượt qua "mô tả tập tin nguyên của tập tin được gói." đến open, điều này có nghĩa là ngoài phương thức str.open(), bạn cũng nhận được int.open(). Đây sẽ là thiết kế OO thực sự tồi tệ nhưng cũng gây nhầm lẫn. Tôi sẽ không quan tâm để đoán những loại câu hỏi sẽ được hỏi về StackOverflow về điều đó ("door".open(), (1).open()) ...

Tuy nhiên tôi phải thừa nhận rằng có một chức năng pathlib.Path.open. Nhưng nếu bạn có một con đường thì nó không còn mơ hồ nữa.

Với chức năng close(): Mỗi trường hợp sẽ có phương thức close() và không có sự khác biệt giữa các lớp khác nhau, vậy tại sao lại tạo một hàm bổ sung? Đơn giản là không có lợi thế.

1

Ngoài những gì đã được nói, tôi trích dẫn các thay đổi trong Python loại bỏ được xây dựng trong loại file. Nó (một thời gian ngắn) giải thích tại sao phương thức khởi tạo lớp bằng cách sử dụng loại file (có sẵn trong Python 2) đã bị loại bỏ trong Python 3:

Loại bỏ loại tệp. Sử dụng mở(). Hiện có một số loại luồng khác nhau mở có thể trả về trong mô-đun io.

Về cơ bản, trong khi file("filename") sẽ tạo ra một thể hiện của file, open("filename") có thể trở lại trường hợp của lớp dòng khác nhau, tùy thuộc vào chế độ.

https://docs.python.org/3.4/whatsnew/3.0.html#builtins

Các vấn đề liên quan