Testing the availability of a module

B

Bo Peng

Dear list,

Is there a better way than doing

try:
import aModule
except:
has_aModule = False
else:
has_aModule = True

The main concern here is that loading aModule is unnecessary (and may
take time).

Many thanks in advance.
Bo
 
?

=?ISO-8859-1?Q?Gerhard_H=E4ring?=

Bo said:
Dear list,

Is there a better way than doing

try:
import aModule
except:
has_aModule = False
else:
has_aModule = True

The main concern here is that loading aModule is unnecessary (and may
take time).

No, there is not really a better way.

You *could* check for the existance of files, but a file existing and it
really being successfully loadable as a module are not the same.

Besides, it is a lot of work to reimplement half the Python import
machinery just for checking for all kinds of files. If you're serious
about it, you also need to cope with modules loadable from ZIP files,
and with .pth files, etc.

This is not fun to program, and you're really better off just checking
for a successful import like you're doing now.

-- Gerhard
 
R

Robert Kern

Gerhard said:
No, there is not really a better way.

You *could* check for the existance of files, but a file existing and it
really being successfully loadable as a module are not the same.

Besides, it is a lot of work to reimplement half the Python import
machinery just for checking for all kinds of files. If you're serious
about it, you also need to cope with modules loadable from ZIP files,
and with .pth files, etc.

*Unless*, someone else has already done all of it for you:

http://peak.telecommunity.com/DevCenter/PythonEggs
http://peak.telecommunity.com/DevCenter/PkgResources

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
T

Thomas Heller

Gerhard Häring said:
No, there is not really a better way.

You *could* check for the existance of files, but a file existing and
it really being successfully loadable as a module are not the same.

Besides, it is a lot of work to reimplement half the Python import
machinery just for checking for all kinds of files. If you're serious
about it, you also need to cope with modules loadable from ZIP files,
and with .pth files, etc.

This is not fun to program, and you're really better off just checking
for a successful import like you're doing now.

I don't think the above is entirely correct. imp.find_module() probably
does what the OP needs.

Thomas
 
S

Steven D'Aprano

Dear list,

Is there a better way than doing

try:
import aModule
except:
has_aModule = False
else:
has_aModule = True

Do you mean to catch every possible exception when importing aModule?

If you replace "except:" with "except ImportError:" then only actual
import errors will be caught. Any other errors in aModule (such as syntax
errors, etc. will still raise a exception as normal.

The main concern here is that loading aModule is unnecessary (and may
take time).

If importing aModule is unnecessary, then just don't import it.

What are you trying to protect against?
 
P

Peter Hansen

Bo said:
Is there a better way than doing

try:
import aModule
except:
has_aModule = False
else:
has_aModule = True

The main concern here is that loading aModule is unnecessary (and may
take time).

Loading a module does *not* take time after the first time. All it does
is pull a reference out of sys.modules. Are you worried about doing the
above multiple times and wasting time? Don't... you'll never notice it.

(And if you aren't doing the above multiple times, then you *really*
shouldn't be worried about the time to load "aModule", unless you have
reason to believe merely loading it takes an incredibly long time, in
which case it is probably poorly designed as most modules should not be
doing real work just by being imported.)

-Peter
 
B

Bo Peng

> And if you aren't doing the above multiple times, then you *really*
> shouldn't be worried about the time to load "aModule"

This is used in a scenario like:

if wxPython is available:
prepare wx based GUI
elif Tkinter is available:
prepare tk based GUI
else:
command line only

Since a user may prefer command line so wxPython/tkinter should not be
actually loaded before the GUI function is called.

Bo
 
S

Steven D'Aprano

This is used in a scenario like:

if wxPython is available:
prepare wx based GUI
elif Tkinter is available:
prepare tk based GUI
else:
command line only

Since a user may prefer command line so wxPython/tkinter should not be
actually loaded before the GUI function is called.

Since that is a choice, it shouldn't depend on the availability of a
module:


if user_preferences["commandline"]:
build CLI
run CLI
else:
try:
import wxPython
build wx GUI
except ImportError:
try:
import tkinter
build tk GUI
except ImportError:
raise NoAvailableGuiError
run GUI
 
F

Fredrik Lundh

Bo said:
This is used in a scenario like:

if wxPython is available:
prepare wx based GUI
elif Tkinter is available:
prepare tk based GUI
else:
command line only

Since a user may prefer command line so wxPython/tkinter should not be
actually loaded before the GUI function is called.

if the user happens to prefer the command line interface, why bother looking
for a GUI ? sounds like you haven't really thought this through...

here's an outline that matches your use case:

if user wants command line:
command line only
else:
if wxPython is available:
prepare wx based GUI
elif Tkinter is available:
prepare tk based GUI
else:
command line only

</F>
 
B

Bo Peng

if the user happens to prefer the command line interface, why bother looking
for a GUI ? sounds like you haven't really thought this through...

here's an outline that matches your use case:

if user wants command line:
command line only
else:
if wxPython is available:
prepare wx based GUI
elif Tkinter is available:
prepare tk based GUI
else:
command line only

This is exactly the logic I use,... Eliminating all unrelated stuff, I
have something like (thanks for the imp hint):

def wxGUI():
import wx
wx...

def tkGUI():
import Tkinter as tk
tk....

def cml():
command line

def GUI():
if options['cml']:
cml()
else:
if imp.find_module('wx'):
wxGUI()
elif imp.find_module('Tkinter'):
tkGUI()
else:
cml()

After a user loads this module (without wx loaded automatically as
before), he can call cml() or GUI().

Bo
 
F

Fredrik Lundh

Bo said:
here's an outline that matches your use case:

if user wants command line:
command line only
else:
if wxPython is available:
prepare wx based GUI
elif Tkinter is available:
prepare tk based GUI
else:
command line only

This is exactly the logic I use,... Eliminating all unrelated stuff, I
have something like (thanks for the imp hint):

def wxGUI():
import wx
wx...

def tkGUI():
import Tkinter as tk
tk....

def cml():
command line

def GUI():
if options['cml']:
cml()
else:
if imp.find_module('wx'):

that imp call is completely unnecessary, and means that you'll scan
the path *twice* for each module, instead of once.

this is more efficient:

try:
wxGUI()
except ImportError:
try:
tkGUI()
except ImportError:
cml()

</F>
 
P

Peter Otten

Bo said:
def GUI():
if options['cml']:
cml()
else:
if imp.find_module('wx'):
wxGUI()
elif imp.find_module('Tkinter'):
tkGUI()
else:
cml()

On the other hand, I don't see how this is superior to an exception-based
approach...

def GUI():
if options["cml"]:
cml()
else:
for ui in wxGUI, tkGUI, cml:
try:
ui()
except ImportError:
pass
else:
break

....especially as you have to deal with ImportError exceptions, too:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ImportError: No module named not_there

Peter
 
E

Erik Max Francis

Bo said:
Is there a better way than doing

try:
import aModule
except:
has_aModule = False
else:
has_aModule = True

The main concern here is that loading aModule is unnecessary (and may
take time).

Yes. Specifically catch ImportError in your except clause.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top