2015-01-30 20 views
20

Tôi nhận thấy Flask đã sử dụng Werkzeug để __import__ một mô-đun và tôi hơi bối rối. Tôi đã xem các tài liệu trên đó và thấy rằng nó dường như giúp bạn kiểm soát nhiều hơn bằng cách nào đó về vị trí của mô-đun, nhưng tôi không chắc chắn chính xác như thế nào và tôi không biết nó khác với importlib.import_module như thế nào .nhập khẩu so với __import __() vs importlib.import_module()?

Điều kỳ lạ trong ví dụ Werkzeug là nó chỉ nói __import__(import_name), vì vậy tôi không thấy khác biệt gì so với chỉ sử dụng câu lệnh import vì nó bỏ qua các tham số phụ tùy chọn.

Có ai giải thích được không? Tôi nhìn vào những người khác đã hỏi những câu hỏi tương tự trên SO trước đây nhưng họ không phải là câu hỏi rất rõ ràng và câu trả lời đã không giải quyết điều này cả.

+1

Sử dụng '__import__' nơi' bạn muốn nhập một module có tên duy nhất được biết tại runtime'. Khác với cái này...như bạn đã nói điều này mang lại cho bạn nhiều quyền lực hơn so với nhập –

+0

Nếu bộ nhớ phục vụ chính xác có một video David Beasely khi nhập, trong video, anh ta đề cập đến việc nhập WerkZeug quá tải vì một lý do nào đó. – Carel

Trả lời

34

__import__ là hàm móc mức thấp được sử dụng để nhập mô-đun; nó có thể được sử dụng để nhập một mô-đun động bằng cách đặt tên mô-đun để nhập dưới dạng biến, điều mà báo cáo import sẽ không cho phép bạn thực hiện.

importlib.import_module() là trình bao bọc xung quanh móc đó * để tạo API tốt cho chức năng; nó là một bổ sung gần đây cho Python 2, và đã được thêm thịt trong Python 3. Codebases sử dụng __import__ thường làm như vậy bởi vì họ muốn vẫn tương thích với các phiên bản Python 2 cũ hơn, ví dụ bất cứ điều gì trước Python 2,7.

Một tác dụng phụ khi sử dụng __import__ có thể là nó trả về mô-đun đã nhập và không thêm bất kỳ thứ gì vào không gian tên; bạn có thể nhập với nó mà không cần phải xóa tên mới nếu bạn không muốn tên mới đó; sử dụng import somename sẽ thêm somename vào không gian tên của bạn, nhưng thay vào đó, __import__('somename') trả về mô-đun đã nhập mà bạn có thể bỏ qua. Werkzeug sử dụng móc cho lý do đó tại một địa điểm.

Tất cả các mục đích sử dụng khác liên quan đến nhập khẩu động. Werkzeug hỗ trợ Python 2.6 vẫn không thể sử dụng importlib.


*importlib là một thực hiện Pure-Python, và import_module() sẽ sử dụng thực hiện điều đó, suýt __import__ sẽ sử dụng một phiên bản C được tối ưu hóa. Cả hai phiên bản gọi trở lại importlib._bootstrap._find_and_load() do đó sự khác biệt chủ yếu là học tập.

+0

Tôi không hiểu ý của bạn là gì bởi "bạn có thể nhập với nó mà không cần xóa tên mới nếu bạn không muốn tên mới đó". Nếu bạn có một phút có thể bạn có thể xác thịt như thể bạn đang nói chuyện với một đứa trẻ? – Aerovistae

+0

@Aerovistae: đã cập nhật một chút; 'import sys' thêm tên' sys' vào namespace của bạn (ràng buộc với module), '__import __ ('sys')' trả về đối tượng 'sys' module cho người gọi, sau đó tự do bỏ qua đối tượng đó. –

+0

@MartijnPieters Bởi không gian tên, bạn có nghĩa là 'sys.modules'? – NeoWang

3

__import__(import_name), vì vậy tôi không thấy như thế nào đó là bất kỳ khác nhau từ chỉ sử dụng câu lệnh import

Cả __import__() và importlib.import_module() cho phép bạn nhập một mô-đun khi bạn có các mô-đun tên dưới dạng một chuỗi. Bạn không thể viết:

x = 're' 
import x 

hoặc bạn sẽ nhận được:

File "1.py", line 3, in <module> 
import x ImportError: No module named x 
Các vấn đề liên quan