2010-09-10 33 views
5

Tôi đã viết một dòng mã sử dụng lambda để đóng một danh sách các đối tượng tập tin trong python2.6:Không thể đóng tệp theo cách chức năng trong python3.1?

map(lambda f: f.close(), files) 

Nó hoạt động, nhưng không ở python3.1. Tại sao?

Đây là mã của tôi kiểm tra:

import sys 

files = [sys.stdin, sys.stderr] 

for f in files: print(f.closed) # False in 2.6 & 3.1 

map(lambda o : o.close(), files) 

for f in files: print(f.closed) # True in 2.6 but False in 3.1 

for f in files: f.close()   

for f in files: print(f.closed) # True in 2.6 & 3.1 

Trả lời

6

map trả về một danh sách bằng Python 2, nhưng một iterator bằng Python 3. Vì vậy, các tập tin sẽ đóng cửa chỉ khi bạn duyệt qua kết quả.

Không bao giờ áp dụng map hoặc các chức năng "chức năng" tương tự cho các chức năng có tác dụng phụ. Python không phải là một ngôn ngữ chức năng, và sẽ không bao giờ. Sử dụng vòng lặp for:

for o in files: 
    o.close() 
+0

Cũng lưu ý rằng 2to3 bắt được điều này và sẽ tự động liệt kê (...) cuộc gọi bản đồ cho bạn, buộc đánh giá ngay lập tức. –

+3

'Không bao giờ áp dụng các chức năng "chức năng" hoặc bản đồ tương tự cho các chức năng có tác dụng phụ. Python không phải là một ngôn ngữ chức năng, và sẽ không bao giờ được. ' Tôi không hiểu tại sao điều này không phải là lời khuyên âm thanh ngay cả khi python là một ngôn ngữ chức năng. Chỉ đơn giản là không có điểm trong việc sử dụng bản đồ nếu bạn không sử dụng kết quả - bằng bất kỳ ngôn ngữ nào. – sepp2k

+0

Trong các hàm ngôn ngữ thuần túy chức năng không có tác dụng phụ, do đó, một hàm 'close()' không thể tồn tại. – Philipp

4

Do bản đồ trong Python 3 là trình lặp lười biếng. Trích dẫn the docs:

Trả về trình lặp áp dụng chức năng cho mọi mục có thể lặp lại, cho kết quả.

Ví dụ: trong Python 2, map(f, seq) tương đương với [f(i) for i in seq], nhưng trong Python 3, nó là (f(i) for i in seq) - cú pháp tinh tế khác nhau, nhưng ngữ nghĩa rất khác nhau. Để biến bản đồ hoạt động, bạn cần tiêu thụ trình lặp. Ergo, nó đơn giản hơn (và thành ngữ hơn: bản đồ, hiểu và máy phát không nên có tác dụng phụ!) Để sử dụng một vòng lặp rõ ràng.

+1

Theo ý kiến ​​của tôi, họ đã để lại 'map()' một mình và làm cho phương thức 'imap()' của mô đun itertools được xây dựng sẵn. Thay vào đó tất cả 'họ' đã giới thiệu một sự không tương thích lớn hơn bằng cách thay đổi những gì hiện có sẵn. – martineau

+0

Ngoài ra, để lại 'map()' một mình và làm cho 'imap()' một built-in sẽ có theo triết lý "Rõ ràng là tốt hơn là ngầm" tốt hơn. – martineau

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