Bagaimana cara mendapatkan referensi ke modul di dalam modul itu sendiri?

159

Bagaimana saya bisa mendapatkan referensi ke modul dari dalam modul itu? Juga, bagaimana saya bisa mendapatkan referensi ke paket yang berisi modul itu?

Ram Rachum
sumber
7
Saya menduga Anda mungkin mengajukan pertanyaan ini karena Anda memiliki variabel dalam cakupan modul (misalnya, BLAH = 10 di luar fungsi atau kelas), lalu variabel kelas / fungsi bernama BLAH, dan Anda ingin membedakan. Pertanyaan yang valid di sini adalah: Apakah ini perlu? Aturan cakupan terkenal rentan terhadap kesalahan, terutama oleh 'idiot' yang mengambil kode Anda setelah Anda (yaitu, Anda, 6 bulan kemudian). Trik seperti ini jarang diperlukan; Saya berusaha menghindarinya sepenuhnya karena mereka seringkali membingungkan dan salah dimodifikasi nantinya.
Kevin J. Rice
2
@ KevinJ.Buat "si idiot 'yang mengambil kode Anda setelah Anda (yaitu, Anda, 6 bulan kemudian)" membuat hari saya!
arctelix
8
Siapa yang peduli mengapa dia mengajukan pertanyaan? Ada banyak alasan sah untuk melakukan ini.
Christopher Barber
Perlu ditutup. Terlalu berguna
mlvljr

Jawaban:

212
import sys
current_module = sys.modules[__name__]
truppo
sumber
3
kecuali untuk ini tidak akan benar jika modul dimuat ulang; Saya tidak berpikir ada tempat di mana referensi dijamin untuk disimpan, jika ada, memuat ulang tidak akan bekerja, kan?
Dima Tisnek
14
Reload kembali menggunakan objek modul yang sama; tidak ada objek modul baru yang dibuat, jadi masih benar saat menghadapi pemuatan ulang.
bukzor
18

Satu lagi teknik, yang tidak mengimpor modul sys, dan bisa dibilang - tergantung selera Anda - lebih sederhana:

current_module = __import__(__name__)

Sadarilah tidak ada impor. Python mengimpor setiap modul hanya sekali.

Uri
sumber
Ini sepertinya cara yang sangat bagus untuk menghindari impor sys. Selain menjadi sedikit kontra-intuitif untuk membaca, adakah potensi kerugian dari pendekatan ini?
JeremyDouglass
@JeremyDouglass. Bukannya aku sadar. impor adalah fungsi yang sah, terdokumentasi, bawaan (satu-satunya fungsi xx ). Anda dapat menggantinya dengan paket 'importlib' (Anda harus mengimpornya). Mungkin - tidak pernah terjadi pada saya - Anda dapat memiliki masalah dengan impor relatif / absolut, jika modul dengan nama yang sama tersedia di sys.path, dalam hal ini Anda dapat menyelesaikannya dengan argumen 'level' dari fungsi.
Uri
16

Jika Anda memiliki kelas dalam modul itu, maka __module__properti kelas adalah nama modul kelas tersebut. Dengan demikian Anda dapat mengakses modul melalui sys.modules[klass.__module__]. Ini juga berfungsi untuk fungsi.

Michael
sumber
4
Sebenarnya, tampaknya (setidaknya) untuk suatu fungsi, __module__properti bukan modul, tetapi sebuah string; dengan demikian inspect.getabsfile(func.__module__)gagal dengan " TypeError: 'os' bukan modul, kelas, metode, fungsi, traceback, bingkai, atau objek kode "; sementara inspect.getabsfile(sys.modules[o.__module__])tampaknya berlalu.
sdaau
12

Anda bisa mendapatkan nama modul saat ini menggunakan __name__

Referensi modul dapat ditemukan di sys.moduleskamus.

Lihat dokumentasi Python

pkit
sumber
1

Anda bisa meneruskannya dari luar:

mymod.init(mymod)

Tidak ideal tetapi berfungsi untuk kasus penggunaan saya saat ini.

Sam Watkins
sumber