2017年7月11日 星期二

[ 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. 

How-To 

Python2 
To check if import can find something in python2, using imp: 
  1. import imp  
  2. try:  
  3.     imp.find_module('eggs')  
  4.     found = True  
  5. except ImportError:  
  6.     found = False  
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  
You can also use pkgutil.find_loader (more or less the same as the python3 part): 
  1. import pkgutil  
  2. eggs_loader = pkgutil.find_loader('eggs')  
  3. found = eggs_loader is not None  
Python3 <= 3.3 
You should 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)  
Python3 >= 3.4 
In Python3.4 importlib.find_loader python docs was deprecated in favour of importlib.util.find_spec. Really, you need to choose any concrete implementation, recomended is the importlib.util.find_spec one. There are others like importlib.machinery.FileFinder, which is useful if you're after a specific file to load. Figuring out how to use them is beyond the scope of this. 
  1. import importlib  
  2. spam_spec = importlib.util.find_spec("spam")  
  3. found = spam_spec is not None  
This also works with relative imports but you must supply the starting package, so you could also do: 
  1. import importlib  
  2. spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")  
  3. found = spam_spec is not None  
  4. spam_spec.name == "eggs.spam"  
WARNING 
When trying to find a submodule, it will import the parent module (for all of the above methods)! 
>>> import importlib 
>>> spam_spec = importlib.import_module("food.eggs") 
>>> spam_spec 
 
>>> numpy_spec = importlib.import_module("numpy") 
>>> numpy_spec 


沒有留言:

張貼留言

[ Py DS ] Ch1 - IPython: Beyond Normal Python

Source From  Here   Keyboard Shortcuts in the IPython Shell   If you spend any amount of time on the computer, you’ve probably found a u...