Difference between import and execfile
There are many differences, but from your point of view the most significant is probably the one that import
gives you more control over the namespace in which the objects defined utils.py
end in.
Let's consider three options import
. The first is the one you asked about:
import utils
utils.f1()
utils
is the only symbol that has been added to your workspace - any pre-existing f1
database in your workspace will not be overwritten, and if not, it f1()
will not be recognized by itself. For code that I intend to maintain, I very much prefer this import method because it makes it easier for me to find my source file for all the places it depends on utils
.
But if it's utils.f1()
too verbose every time, you can do this:
from utils import f1
f1()
Now, if you say f1()
, is called utils.f1()
because it is a code object that you have now associated with a name f1
in your workspace. Now it's a little trickier to get an overview of where your code depends on a module utils
. But at least this type of operator import
gives you precise control over which symbols were imported and which were not. You can even rename symbols during this process:
from utils import f1 as EffOne
EffOne()
Finally, you can completely lose control of the namespace:
from utils import *
Now, who knows what symbols were imported: basically everything that has utils
to offer the world (or, if the developer utils
took it upon himself __all__
to specify the attribute __all__
, then everything listed there). I would suggest you import *
only use it for quick and dirty programming, if at all.
This is actually the import style closest to execfile
in terms of the namespace: execfile('utils.py')
it does the same as from utils import *
because it dumps all utils
willy-nilly-defined characters into your workspace.One slight difference is that execfile
it is not even limited to characters in __all__
if it is defined - in fact, the __all__
symbol is __all__
simply discarded on your circle along with everything else.
Apart from namespaces, there are still many differences between from utils import *
and execfile('utils.py')
. One of them - Caching: second call import
to utils
be very fast (the code will not be re-started), but the second call, execfile('utils.py')
it may take as much time as the first, because the code will restart. Also, there utils.py
might be some code inside (code that is frequently checked) that the author utils
does not want to run during import, but only when the file is executed through execfile
. This code is placed inside if __name__ == '__main__':
.
source to share