2009-06-29 36 views
15

Tôi có một thư mục tin nhắn (gói) với tập tin __init__.py và một mô-đun khác messages_en.py bên trong nó. Trong __init__.py nếu tôi nhập messages_en nó hoạt động, nhưng __import__ không thành công với "ImportError: Không có mô-đun tên messages_en"Làm cách nào để nhập gói bằng __import __() khi tên gói chỉ được biết khi chạy?

import messages_en # it works 
messages = __import__('messages_en') # it doesn't ? 

Tôi đã từng nghĩ 'nhập khẩu x' chỉ là một cách khác để nói __import__('x')

Trả lời

14

Thêm đối số globals là đủ cho tôi:

__import__('messages_en', globals=globals()) 

Trong thực tế, chỉ __name__ là cần thiết ở đây:

__import__('messages_en', globals={"__name__": __name__}) 
14

__import__ là một chức năng nội bộ được gọi bằng lệnh nhập. Trong hàng ngày mã hóa bạn không cần (hoặc muốn) để gọi __import__

từ tài liệu python:

Ví dụ, báo cáo kết quả import spam kết quả trong bytecode giống như đoạn mã sau:

spam = __import__('spam', globals(), locals(), [], -1) 

Trên Mặt khác, báo cáo kết quả from spam.ham import eggs, sausage as saus kết quả trong

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1) 
eggs = _temp.eggs 
saus = _temp.sausage 

chi tiết: http://docs.python.org/library/functions.html

+1

+1 và nhờ giải thích, nhưng bạn có thể mô tả chính xác lý do tại sao Ví dụ của OP không hoạt động? Anh ta dường như đang cố gắng để bí danh messages_en tin nhắn, mà có vẻ (ngây thơ với tôi) là hợp lý. –

+0

Như 'wr' giải thích là do cấp độ, và tôi biết __import__ không nên thường được sử dụng nhưng trong trường hợp này tôi phải tự động đọc ngôn ngữ từ tệp cấu hình gắn thêm vào thư và nhập tệp đó –

+0

Ví dụ này rất hữu ích, đặc biệt là nếu bạn đang cố gắng tải các mô-đun từ các thư mục con. Nó đã giúp tôi sửa lỗi "Không tìm thấy thuộc tính" của tôi. – Carlos

19

Nếu nó là một vấn đề con đường, bạn nên sử dụng lập luận level (từ docs):

__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module 

Level is used to determine whether to perform 
absolute or relative imports. -1 is the original strategy of attempting 
both absolute and relative imports, 0 is absolute, a positive number 
is the number of parent directories to search relative to the current module. 
+2

nhưng tôi tự hỏi lý do là gì, bởi vì mức mặc định là -1, và tôi vẫn đi qua -1, vì vậy chỉ thêm là toàn cầu/địa phương dict, làm thế nào mà làm cho một sự khác biệt –

+0

Tại sao câu trả lời được chấp nhận? Nó không trả lời câu hỏi hay giải quyết vấn đề. – kynan

+0

Câu trả lời này là sai. Vấn đề của OP không liên quan đến 'cấp độ' theo bất kỳ cách nào. Hai tùy chọn để sửa chữa nó: Hoặc cung cấp các globals của module như 'messages = __import __ ('messages_en', globals())' như Eric chỉ ra hoặc đặt tên gói như Lennart gợi ý. – kynan

0

Bạn có thể thử này:

messages == __import__('Foo.messages_en', fromlist=['messages_en']) 
3

Hãy chắc chắn để thêm thư mục modules vào đường dẫn python của bạn.

Đường dẫn của bạn (danh sách thư mục Python đi qua để tìm kiếm mô-đun và tệp) được lưu trữ trong thuộc tính đường dẫn của mô-đun sys. Vì đường dẫn là một danh sách bạn có thể sử dụng phương thức chắp thêm để thêm các thư mục mới vào đường dẫn.

Ví dụ, để thêm thư mục/home/me/mypy đến đường dẫn:

import sys 
sys.path.append("/home/me/mypy") 
+1

Điều đó không an toàn vì nó làm cho gói không thể định vị lại. Nó sẽ chỉ hoạt động nếu gói nằm trong đường dẫn được mã hóa cứng này. – kynan

0

Bạn cần nhập thủ công gói hàng đầu của đường dẫn gói động của bạn.

Ví dụ trong phần đầu của file tôi viết:

import sites 

sau đó trong mã này làm việc cho tôi:

target = 'some.dynamic.path' 
my_module = __import__ ('sites.%s.fabfile' % target, fromlist=["sites.%s" % target]) 
Các vấn đề liên quan