I have a file utils.py containing a function called f1().
From another Python script I can import utils or execfile('utils.py') and have access to f1(). What are the differences between the two methods?
I have a file utils.py containing a function called f1().
From another Python script I can import utils or execfile('utils.py') and have access to f1(). What are the differences between the two methods?
Copyright © 2021 Jogjafile Inc.
There are many differences, but from your point of view the most significant is probably that
importgives you more control over the namespace in which the objects defined inutils.pyend up.Let's consider three variants on
import. The first is the one you asked about:utilsis the only symbol that has been added to your workspace—any pre-existingf1in your base workspace will not have been overwritten, and if there is none, thenf1()on its own will not be recognized. For code I intend to maintain, I greatly prefer this way of importing, because it makes it easy for me to search my source file for all the places in which it depends onutils.But if saying
utils.f1()every time is too verbose then you can do this:Now if you say
f1()that will callutils.f1(), because that is the code object that you have now associated with the namef1in your workspace. It's now slightly harder to get an overview of where your code is reliant on theutilsmodule. But at least this type ofimportstatement gives you precise control over which symbols were imported and which not. You can even rename symbols during this process:Finally you can choose to lose control over the namespace entirely:
Now, who knows what symbols have been imported: basically everything that
utilshas to offer the world (or, if theutilsdeveloper took the trouble to specify an__all__attribute, then everything listed there). I'd advise you to useimport *only for quick-and-dirty programming, if at all.This is actually the importing style that is closest to
execfilefrom the namespace point of view:execfile('utils.py')does much the same asfrom utils import *in that it dumps all symbols defined byutilswilly-nilly into your workspace. One slight difference is thatexecfilewon't even limit itself to the symbols in__all__if that is defined—in fact, the__all__symbol itself will just get dumped in your lap along with everything else.Beyond namespaces, there are still plenty of differences between
from utils import *andexecfile('utils.py'). One is caching: a secondimportcall onutilswill be very fast (the code will not be re-run), but a second call toexecfile('utils.py')may take just as long as the first because the code will be re-run. Also, there may be some code (often test code) insideutils.pythat theutilsauthor does not want to run at import time, but only when the file is executed viaexecfile. Such code is placed inside anif __name__ == '__main__':clause.