Làm thế nào để có được một tham chiếu đến một mô-đun bên trong chính mô-đun?


158

Làm thế nào tôi có thể có được một tham chiếu đến một mô-đun từ bên trong mô-đun đó? Ngoài ra, làm thế nào tôi có thể có được một tham chiếu đến gói chứa mô-đun đó?


7
Tôi nghi ngờ bạn có thể hỏi câu hỏi này vì bạn có một biến trong phạm vi mô-đun (ví dụ: BLAH = 10 bên ngoài một hàm hoặc lớp), sau đó là một biến lớp / hàm có tên BLAH và bạn muốn phân biệt. Một câu hỏi hợp lệ ở đây là: Điều này có cần thiết không? Các quy tắc phạm vi nổi tiếng là dễ bị nhầm lẫn, đặc biệt là bởi 'kẻ ngốc' nhặt mã của bạn sau bạn (ví dụ: bạn, 6 tháng sau). Thủ thuật như thế này hiếm khi cần thiết; Tôi cố gắng tránh chúng hoàn toàn vì chúng thường gây nhầm lẫn và sửa đổi sai sau này.
Kevin J. Rice

2
@ KevinJ.Rice "'thằng ngốc" nhặt mã của bạn sau khi bạn (tức là bạn, 6 tháng sau) "đã làm nên ngày của tôi!
arctelix

8
Ai quan tâm tại sao anh ta đặt câu hỏi? Có rất nhiều lý do hợp lệ để làm điều này.
Christopher Barber

Cần phải đóng cửa. Quá hữu ích.
mlvljr

Câu trả lời:


211
import sys
current_module = sys.modules[__name__]

3
ngoại trừ điều này sẽ không hoàn toàn chính xác nếu mô-đun được tải lại; Tôi không nghĩ rằng có bất kỳ nơi nào mà tài liệu tham khảo được đảm bảo được lưu giữ, nếu có, việc tải lại sẽ không thực sự hiệu quả, phải không?
Dima Tisnek

14
Tải lại sử dụng lại cùng một đối tượng mô-đun; không có đối tượng mô-đun mới nào được tạo, vì vậy nó vẫn đúng khi tải lại.
bukzor

18

Một kỹ thuật nữa, không nhập mô-đun sys, và có thể nói - tùy thuộc vào sở thích của bạn - đơn giản hơn:

current_module = __import__(__name__)

Hãy lưu ý rằng không có nhập khẩu. Python chỉ nhập mỗi mô-đun một lần.


Đây có vẻ là một cách thực sự tốt đẹp để tránh nhập sys. Khác với việc hơi phản trực giác để đọc có bất kỳ nhược điểm tiềm năng nào đối với phương pháp này không?
JeremyDoulass

@JeremyDoulass. Không phải là tôi biết. nhập khẩu là một hàm hợp pháp, được ghi thành tài liệu ( hàm xx duy nhất ). Bạn có thể thay thế nó bằng gói 'importlib' (bạn sẽ phải nhập nó). Có lẽ - không bao giờ xảy ra với tôi - bạn có thể gặp sự cố với nhập tương đối / tuyệt đối, nếu một mô-đun có cùng tên có sẵn trong sys.path, trong trường hợp đó bạn có thể giải quyết nó bằng đối số 'cấp' của hàm.
Uri

16

Nếu bạn có một lớp trong mô-đun đó, thì thuộc __module__tính của lớp là tên mô-đun của lớp. Do đó bạn có thể truy cập các mô-đun thông qua sys.modules[klass.__module__]. Đây cũng là công trình cho các chức năng.


4
Trên thực tế, dường như (ít nhất) đối với một hàm, thuộc __module__tính không phải là một mô-đun, mà là một chuỗi; do đó, inspect.getabsfile(func.__module__)thất bại với " TypeError: 'os' không phải là mô-đun, lớp, phương thức, chức năng, truy nguyên, khung hoặc đối tượng mã "; Trong khi inspect.getabsfile(sys.modules[o.__module__])dường như vượt qua.
sdaau

12

Bạn có thể lấy tên của mô-đun hiện tại bằng cách sử dụng __name__

Tham chiếu mô-đun có thể được tìm thấy trong sys.modulestừ điển.

Xem tài liệu Python


1

Bạn có thể vượt qua nó từ bên ngoài:

mymod.init(mymod)

Không lý tưởng nhưng nó hoạt động cho trường hợp sử dụng hiện tại của tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.