程式扎記: [ Python 常見問題 ] How to check if a python module exists without importing it

標籤

2015年8月18日 星期二

[ Python 常見問題 ] How to check if a python module exists without importing it

Source From Here
Question
I need to know if a python module exists, without importing it. Importing something that might not exist (not what I want):
  1. try:  
  2.     import eggs  
  3. except ImportError:  
  4.     pass  
How-To
To check if import can find something in python2, using imp:
  1. # -*- coding: utf-8 -*-    
  2. import imp  
  3.   
  4. def chkModExist(mn):  
  5.     try:  
  6.         imp.find_module(mn)  
  7.         return True  
  8.     except ImportError:  
  9.         return False  
  10.       
  11. for mn in ['egg''selenium''os']:  
  12.     print "Module '{0}' exist? {1}".format(mn, chkModExist(mn))  
To find dotted imports, you need to do more:
  1. import imp  
  2. try:  
  3.     spam_info = imp.find_module('spam')  
  4.     spam = imp.load_module('spam', *spam_info)  
  5.     imp.find_module('eggs', spam.__path__) # __path__ is already a list  
  6.     found = True  
  7. except ImportError:  
  8.     found = False  
For a full path module (including dot), below is an example for reference:
  1. # -*- coding: utf-8 -*-    
  2. import imp  
  3. import os.path  
  4.   
  5. def chkModExist(mn, path=None):  
  6.     try:  
  7.         #print "Search moudle='{0}' from '{1}'...".format(mn, path)  
  8.         if path is None:  
  9.             m_info=imp.find_module(mn)  
  10.         else:  
  11.             m_info=imp.find_module(mn, [path])  
  12.         return (True, m_info)  
  13.     except ImportError:  
  14.         return False  
  15.   
  16. md = {}  
  17. print "\t[Info] Loading desired modules..."  
  18. for mn in ['egg''selenium''os''demo.faq.CheckModules']:  
  19.     mn_dot = mn.split(".")  
  20.     lm=None  
  21.     for sm in mn_dot:  
  22.         if lm:  
  23.             if "__init__.py" in lm.__file__:  
  24.                 rt=chkModExist(sm, os.path.dirname(lm.__file__))              
  25.         else:  
  26.             rt=chkModExist(sm)      
  27.         if rt:          
  28.             m_info = rt[1]  
  29.             m=imp.load_module(sm, *m_info)  
  30.             print "\t\tLoading module...{0}/{1}".format(m, m.__file__)  
  31.             lm=m  
  32.         else:  
  33.             print "\t\tModule '{0}' doesn't exist ({1})".format(mn, sm)              
  34.             lm=None  
  35.             break  
  36.     if lm:  
  37.         md[mn]=lm  
  38.           
  39. print "\t[Info] Leverage loaded module 'os' to show env:\n%s" % md['os'].environ  
Here "demo.faq.CheckModules" is a local module for testing. A execution sample output will be:
[Info] Loading desired modules...
Loading module.../C:\Python27\lib\site-packages\egg-0.2.0-py2.7.egg\egg\__init__.pyc
Module 'selenium' doesn't exist (selenium)
Loading module.../C:\Python27\lib\os.pyc
Loading module.../C:\John\Eclipse\PyLab\demo\__init__.pyc
Loading module.../C:\John\Eclipse\PyLab\demo\faq\__init__.pyc
Loading module.../C:\John\Eclipse\PyLab\demo\faq\CheckModules.pyc
[Info] Leverage loaded module 'os' to show env:
{'TMP': 'C:\\Users\\\xab\xb6\xbcy\\AppData\\Local\\Temp', ...}

Python3 wants you to use importlib, How I went about doing this was:
  1. import importlib  
  2. spam_loader = importlib.find_loader('spam')  
  3. found = spam_loader is not None  
My expectation being, if you can find a loader for it, then it exists. You can also be a bit more smart about it, like filtering out what loaders you will accept. For example
  1. import importlib  
  2. spam_loader = importlib.find_loader('spam')  
  3. # only accept it as valid if there is a source file for the module - no bytecode only.  
  4. found = issubclass(type(spam_loader), importlib.machinery.SourceFileLoader)  


沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!