2012-09-25 44 views
13

Nếu một hàm lấy làm đầu vào tên của tệp văn bản, tôi có thể cấu trúc lại để thay thế đối tượng tệp (tôi gọi nó là "luồng"; có từ nào tốt hơn không?). Những lợi thế là hiển nhiên - một chức năng mà phải mất một dòng như một cuộc tranh cãi là:tên tệp vs đối tượng tệp làm đối số hàm

  • dễ dàng hơn nhiều để viết một bài kiểm tra đơn vị cho, vì tôi không cần phải tạo ra một tập tin tạm thời chỉ cho kỳ thi này
  • hơn linh hoạt, vì tôi có thể sử dụng nó trong các tình huống mà bằng cách nào đó tôi đã có nội dung của tệp trong một biến

Có bất kỳ bất lợi nào đối với luồng không? Hoặc tôi nên luôn luôn refactor một chức năng từ một đối số tên tập tin cho một đối số dòng (giả sử, tất nhiên, tập tin là chỉ văn bản)?

Trả lời

4

Có rất nhiều chức năng trong thư viện chuẩn python chấp nhận cả hai chuỗi là tên tệp hoặc đối tượng tệp mở (tôi cho rằng đó là những gì bạn đang đề cập đến dưới dạng "luồng"). Nó thực sự không khó để tạo ra một trang trí mà bạn có thể sử dụng để làm cho các chức năng của bạn chấp nhận một trong hai.

Một hạn chế nghiêm trọng khi sử dụng "luồng" là bạn chuyển nó đến hàm của bạn và sau đó chức năng của bạn đọc từ nó - thay đổi hiệu quả trạng thái của nó. Tùy thuộc vào chương trình của bạn, khôi phục trạng thái đó có thể lộn xộn nếu cần thiết. (Ví dụ như bạn có thể cần phải xả rác bạn mã hóa với f.tell() và sau đó f.seek().)

+0

Có, khi tôi nói "luồng", tôi có nghĩa là "đối tượng tệp mở". Nó sẽ không thể viết một trang trí giúp tiết kiệm và phục hồi trạng thái luồng? – max

+0

Và không có cách nào để tạo bản sao rẻ tiền của luồng, sao cho bản sao sở hữu "con trỏ" của riêng mình, trong khi "con trỏ" của luồng gốc bị bỏ hoang? Điều đó sẽ thậm chí còn sạch hơn so với lưu/khôi phục lại cách tiếp cận trạng thái. – max

+0

@max - Chắc chắn, bạn có thể viết một trang trí để làm điều đó. Điều quan trọng là ghi lại tài liệu khi bạn khôi phục lại trạng thái và khi bạn không ở trạng thái đó. Theo như tạo ra một bản sao, điều duy nhất tôi có thể nghĩ đến là 'itertools.tee', có một chút khác biệt (nhưng nó đã vượt qua giờ đi ngủ bình thường của tôi, vì vậy tôi không đảm bảo bất cứ điều gì mà tôi gõ ngay bây giờ: ^). – mgilson

5

... Sau đây là cách xml.etree.ElementTree mô-đun thực hiện các chức năng parse:

def parse(self, source, parser=None): 
    close_source = False 
    if not hasattr(source, "read"): 
     source = open(source, "rb") 
     close_source = True 
    ... 

Như filename là một chuỗi, nó không có phương pháp read() (ở đây bất kỳ thuộc tính nào của tên đó được chọn); tuy nhiên, tệp mở có nó. Bốn dòng làm cho phần còn lại của mã phổ biến. Biến chứng duy nhất là bạn phải nhớ có nên đóng đối tượng tập tin (ở đây có tên là source) hay không. Nếu nó là open bên trong, thì nó phải được đóng lại. Nếu không, nó không được đóng lại.

Thực ra, các tệp khác với hơi sreams. Các luồng có khả năng vô hạn trong khi các tệp thường không (trừ khi một số thiết bị được ánh xạ như thể nó là tệp). Sự khác biệt quan trọng khi xử lý là, bạn không bao giờ có thể đọc luồng vào bộ nhớ cùng một lúc. Bạn phải xử lý nó theo khối.

+0

Tôi đã tìm kiếm một thực hiện tham khảo về điều này trong stdlib. Cảm ơn vì đoạn mã thực sự tiết kiệm thời gian. Tôi sẽ đưa ra một +1 cho cảnh báo cho các khối nếu tôi có thể. – n611x007

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