Bir python modülünün içe aktarılıp aktarılmadığı nasıl kontrol edilir?


91

Kodun herhangi bir yerine bir modülü içeri aktarıp aktarmadığımı nasıl kontrol ederim?

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

Zaten bir modülü içe aktarıp aktarmadığımı kontrol etmek istememin nedeni, bazen programımı bozduğu için içe aktarmak istemediğim bir modüle sahip olmamdır.


raise SystemError()İçe aktarmak istemediğiniz modülün üstüne (veya seçtiğiniz başka bir istisna) koyun . Eğer varsa do aslında bir yerde içe, programınız bir Traceback ve çıkış fırlatır.
larsks

Bir modülü içe aktarmak programınızı nasıl bozar? Pek olası görünmüyor.
Bill Woodger


@MartijnPieters Yoiks. Ve içe aktarım sesleri çok nötr.
Bill Woodger

Yanıtlar:


122

sys.modulesSözlükteki modül adını test edin :

import sys

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

Dokümantasyondan:

Bu, modül adlarını önceden yüklenmiş modüllerle eşleyen bir sözlüktür.

Bir importifadenin iki şey yaptığını unutmayın:

  1. modül daha önce hiç içe aktarılmamışsa (== içinde mevcut değilse sys.modules), yüklenir ve öğesine eklenir sys.modules.
  2. Modül nesnesine veya modül ad alanının üyeleri olan nesnelere başvuran geçerli ad alanındaki 1 veya daha fazla adı bağlayın.

İfade modulename not in sys.modules, 1. adımın gerçekleşip gerçekleşmediğini test eder. 2. adımın sonucunun test edilmesi, importfarklı nesnelere başvurmak için farklı adlar belirlediklerinden tam olarak hangi ifadenin kullanıldığını bilmeyi gerektirir :

  • import modulename setleri modulename = sys.modules['modulename']
  • import packagename.nestedmodulesetler packagename = sys.modules['packagename'](kaç tane ek seviye eklerseniz ekleyin)
  • import modulename as altname setleri altname = sys.module['modulename']
  • import packagename.nestedmodule as altname setleri altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname setleri objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulenamesetleri nestedmodulename = sys.modules['packagename.nestedmodulename'](adında hiçbir nesne yoktu sadece nestedmodulenameiçinde packagenamebu aktarmadan önce ad, iç içe modül için ilave bir isim bu noktada ana paket ad alanına eklenir)
  • from somemodule import objectname as altname setleri altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altnamesetleri altname = sys.modules['packagename.nestedmodulename'](adında hiçbir nesne yoktu sadece nestedmodulenameiçinde packagenamebu aktarmadan önce ad, iç içe modül için ilave bir isim bu noktada ana paket ad alanına eklenir)

İçe aktarılan nesnenin bağlı olduğu adın belirli bir ad alanında olup olmadığını test edebilirsiniz:

# 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'])

Bu, o modülden belirli bir modüle veya nesneye atıfta bulunup bulunmadığını size yalnızca adın var olduğunu (bağlı olduğunu) söyler. sys.modulesAdın o zamandan beri tamamen başka bir şeye ayarlandığını göz ardı etmeniz gerekiyorsa, o nesneyi daha ayrıntılı olarak inceleyebilir veya içinde mevcut olanla aynı nesne olup olmadığını test edebilirsiniz .


1
Bir işlevin içindeki gerekli paketi kontrol etmenin en iyi yolu bu mu? Yani, diyelim ki bazı işlevler numpypaket gerektirir - import sysiçe aktarılıp aktarılmadığını kontrol etmek için işlevin içinde en iyisi kullanmak mı? "En iyi" ile import sys, daha sonra işlev her çağrıldığında çağrılacağı gibi performans etkisi anlamında kastım . Teşekkürler
Confounded

@Confounded, eğer sizi endişelendiriyorsa, sys'i işlevin dışına aktarabilirsiniz. Bu import syshiçbir şekilde pahalı değil; sysher zaman mevcuttur, varsayılan olarak zaten yüklenmiştir. Ancak isteğe bağlı bir paket için: sadece paketi içe aktarın . ImportErrorPaket kurulu değilse istisnayı yakalayın ve içe aktarma başarılı olduğunda bunun kurulduğunu belirten bir bayrak ayarlayın. Bundan sonra, isteğe bağlı bağımlılık kullanımınızı bildirmek için bayrağı kullanabilirsiniz.
Martijn Pieters

@Confounded name in sys.modulesTest yalnızca içe aktarmak istemiyorsanız kullanışlıdır .
Martijn Pieters

24

Kabul edilen sys.modules yanıtlarına, içe aktarmada modülleri yeniden adlandırma konusunda dikkatli olmak için bir uyarı ekleyeceğim:

>>> import sys
>>> import datetime as dt
>>> 'dt' in sys.modules
False
>>> 'datetime' in sys.modules
True

18

bir modülün içe aktarılıp aktarılmadığını test etmek için sys.modules kullanın (örnek olarak unicodedata kullanıyorum):

>>> import sys
>>> 'unicodedata' in sys.modules
False
>>> import unicodedata
>>> 'unicodedata' in sys.modules
True

5

sys.modules yorumlayıcının geçerli örneğinde herhangi bir yerde kullanılan tüm modülleri içerir ve bu nedenle başka herhangi bir Python modülüne aktarılırsa görünür.

dir() adın mevcut ad alanında tanımlanıp tanımlanmadığını kontrol eder.

2'nin kombinasyonu, her birinden daha güvenlidir ve copykendinizi tanımlamadığınız sürece çalışır .

if ('copy' in sys.modules) and ('copy' in dir()):

0
if "sys" not in dir():
  print("sys not imported!")

Bu yalnızca modülün mevcut ad alanında içe aktarılıp aktarılmadığını kontrol eder. Ayrıca sysherhangi bir şey olabilir, sadece bir modül değil.
vaultah
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.