Bagaimana cara memeriksa apakah modul python telah diimpor?

91

Bagaimana cara memeriksa apakah saya mengimpor modul di suatu tempat dalam kode?

 if not has_imported("somemodule"):
     print('you have not imported somemodule')

Alasan saya ingin memeriksa apakah saya sudah mengimpor modul adalah karena saya memiliki modul yang tidak ingin saya impor karena terkadang program saya kacau.

yuval
sumber
Letakkan saja raise SystemError()(atau pengecualian lain pilihan Anda) di bagian atas modul yang tidak ingin Anda impor. Jika Anda benar - benar mengimpornya ke suatu tempat, program Anda akan melakukan pelacakan dan keluar.
Larsks
Bagaimana cara mengimpor modul saja mengacaukan program Anda? Kedengarannya tidak mungkin.
Bill Woodger
1
@BillWoodger: mungkin modul itu mengubah status global yang tidak ingin Anda ubah .
Martijn Pieters
@Bayu_joo Dan impor terdengar sangat netral.
Bill Woodger
Kemungkinan duplikat dari cara menguji apakah satu modul python telah diimpor?
shadowtalker

Jawaban:

122

Uji nama modul dalam sys.moduleskamus :

import sys

modulename = 'datetime'
if modulename not in sys.modules:
    print 'You have not imported the {} module'.format(modulename)

Dari dokumentasi:

Ini adalah kamus yang memetakan nama modul ke modul yang telah dimuat.

Perhatikan importpernyataan itu melakukan dua hal:

  1. jika modul belum pernah diimpor sebelumnya (== tidak ada di sys.modules ), maka akan dimuat dan ditambahkan ke sys.modules.
  2. Ikat 1 atau beberapa nama di namespace saat ini yang mereferensikan objek modul atau objek yang merupakan anggota namespace modul.

Ekspresi modulename not in sys.modulesmenguji apakah langkah 1 telah dilakukan. Menguji hasil dari langkah 2 memerlukan mengetahui importpernyataan persis apa yang digunakan saat mereka menetapkan nama yang berbeda untuk mereferensikan objek yang berbeda:

  • import modulename set modulename = sys.modules['modulename']
  • import packagename.nestedmoduleset packagename = sys.modules['packagename'](tidak peduli berapa banyak level tambahan yang Anda tambahkan)
  • import modulename as altname set altname = sys.module['modulename']
  • import packagename.nestedmodule as altname set altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname set objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulenameset nestedmodulename = sys.modules['packagename.nestedmodulename'](hanya jika tidak ada objek yang bernama nestedmodulenamedalam packagenamenamespace sebelum impor ini, nama tambahan untuk modul bersarang ditambahkan ke namespace paket induk pada saat ini)
  • from somemodule import objectname as altname set altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altnameset altname = sys.modules['packagename.nestedmodulename'](hanya jika tidak ada objek yang bernama nestedmodulenamedalam packagenamenamespace sebelum impor ini, nama tambahan untuk modul bersarang ditambahkan ke namespace paket induk pada saat ini)

Anda dapat menguji apakah nama yang mengikat objek yang diimpor ada di namespace tertentu:

# is this name visible in the current scope:
'importedname' in dir()

# or, is this a name in the globals of the current module:
'importedname' in globals()

# or, does the name exist in the namespace of another module:
'importedname' in globals(sys.modules['somemodule'])

Ini hanya memberi tahu Anda nama yang ada (telah terikat), bukan jika itu merujuk ke modul atau objek tertentu dari modul itu. Anda dapat lebih jauh melakukan introspeksi objek itu atau menguji apakah itu objek yang sama dengan yang tersedia di sys.modules, jika Anda perlu mengesampingkan bahwa nama telah disetel ke sesuatu yang lain sepenuhnya sejak saat itu.

Martijn Pieters
sumber
1
Apakah ini cara terbaik untuk memeriksa paket yang diperlukan di dalam suatu fungsi? Artinya, katakanlah beberapa fungsi memerlukan numpypaket - apakah menggunakan import sysdi dalam fungsi adalah yang terbaik untuk memeriksa bahwa ia telah diimpor? Yang saya maksud dengan "terbaik" adalah dalam kaitannya dengan dampak kinerja yang import sysakan dipanggil setiap kali fungsi tersebut dipanggil. Terima kasih
Bingung pada
@Confounded, Anda dapat mengimpor sys di luar fungsi jika itu membuat Anda khawatir. Bukan berarti import sysitu mahal; sysselalu ada, secara default sudah dimuat. Tetapi untuk paket opsional: cukup impor paketnya . Tangkap ImportErrorpengecualian jika paket tidak diinstal, dan setel tanda yang menunjukkan bahwa paket tersebut diinstal saat impor berhasil. Setelah itu Anda bisa menggunakan flag untuk menginformasikan penggunaan dependensi opsional Anda.
Martijn Pieters
@Confounded name in sys.modulesPengujian ini hanya berguna jika Anda tidak ingin mengimpor .
Martijn Pieters
24

Untuk jawaban sys.modules yang diterima, saya akan menambahkan satu peringatan untuk berhati-hati dalam mengganti nama modul saat impor:

>>> import sys
>>> import datetime as dt
>>> 'dt' in sys.modules
False
>>> 'datetime' in sys.modules
True
morvan68.dll
sumber
18

gunakan sys.modules untuk menguji apakah modul telah diimpor (saya menggunakan unicodedata sebagai contoh):

>>> import sys
>>> 'unicodedata' in sys.modules
False
>>> import unicodedata
>>> 'unicodedata' in sys.modules
True
Haresh Shyara
sumber
5

sys.modules berisi semua modul yang digunakan di mana saja dalam instance interpreter saat ini dan muncul jika diimpor dalam modul Python lainnya.

dir() memeriksa apakah nama itu didefinisikan di namespace saat ini.

Kombinasi dari 2 lebih aman daripada masing-masing terpisah dan berfungsi selama Anda tidak mendefinisikan copydiri sendiri.

if ('copy' in sys.modules) and ('copy' in dir()):
HansW
sumber
0
if "sys" not in dir():
  print("sys not imported!")
rundekugel.dll
sumber
Itu hanya memeriksa apakah modul diimpor di namespace saat ini. Juga sysbisa apa saja, bukan hanya modul.
vaultah