I have always been using this method:

from sys import argv

and use argv with just argv. But there is a convention of using this:

import sys

and using the argv by sys.argv

The second method makes the code self documented and I (really) adhere to it. But the reason I prefer first method is it is fast because we are importing only the function that is needed rather than import the whole module (which contains more useless functions which python will waste time importing them). Note that I need just argv and all other functions from sys are useless to me.

So my questions are. Does the first method really makes the script fast? Which method is preferred most? Why?

up vote 147 down vote accepted

Importing the module doesn't waste anything; the module is always fully imported (into the sys.modules mapping), so wether you use import sys or from sys import argv makes no odds.

The only difference between the two statements is what name is bound; import sys binds the name sys to the module (so sys -> sys.modules['sys']), while from sys import argv binds a different name, argv, pointing straight at the attribute contained inside of the module (so argv -> sys.modules['sys'].argv). The rest of the sys module is still there, whether you use anything else from the module or not.

There is also no performance difference between the two approaches. Yes, sys.argv has to look up two things; it has to look up sys in your global namespace (finds the module), then look up the attribute argv. And yes, by using from sys import argv you can skip the attribute lookup, since you already have a direct reference to the attribute. But the import statement still has to do that work, it looks up the same attribute when importing, and you'll only ever need to use argv once. If you had to use argv thousands of times in a loop it could perhaps make a difference, but in this specific case it really does not.

The choice between one or the other then, should be based on coding style instead.

In a large module, I'd certainly use import sys; code documentation matters, and using sys.argv somewhere in a large module makes it much clearer what you are referring to than just argv ever would.

If the only place you use argv is in a '__main__' block to call a main() function, by all means use from sys import argv if you feel happier about that:

if __name__ == '__main__':
    from sys import argv

I'd still use import sys there myself. All things being equal (and they are, exactly, in terms of performance and number of characters used to write it), that is just easier on the eye for me.

If you are importing something else altogether, then perhaps performance comes into play. But only if you use a specific name in a module many times over, in a critical loop for example. But then creating a local name (within a function) is going to be faster still:

 import somemodule

 def somefunction():
      localname = somemodule.somefunctionorother
      while test:
          # huge, critical loop
          foo = localname(bar)
  • 1
    There is also the situation where you have a package with subpackages or modules that exposes an attribute of one of those subpackages/modules in the top level package. Using from...import allows you to do package.attribute rather than package.subpackage_or_module.attribute, which can be useful if you have logical or conceptual groupings within the package but want to make things a bit more convenient for users of your package. (numpy does something like this, I believe.) – JAB Jan 30 '14 at 16:59
  • In django you have tons of spots where things like from django.core.management.base import BaseCommand are better,and anything else (especially import django) would lead to unreadable code. So while I like this answer, I think there are some libraries (and especially some frameworks) in which the convention is to violate the bare import. As always, use your judgment about what is best in a given situation. But err on the side of explicit (in other words I agree for the most part). – neuronet Jan 3 at 17:24

There are two reasons in favor of using import module rather than from module import function.

First is the namespace. Importing a function into the global namespace risks name collisions.

Second isn't that relevant to standard modules, but significant for you own modules, especially during development. It's the option to reload() a module. Consider this:

from module import func
# func still points to the old code

On the other hand

import module
# module.func points to the new code

As for speed...

we are importing only the function that is needed rather than import the whole module (which contains more useless functions which python will waste time importing them)

Whether you import a module or import a function from a module, Python will parse the whole module. Either way the module is imported. "Importing a function" is nothing more than binding the function to a name. In fact import module is less work for interpreter than from module import func.

  • 2
    reload() was a builtin in Python 2; that is no longer the case for Python 3. – André Sep 8 '17 at 17:38

In my opinion using regular import improves readability. When reviewing Python code I like seeing where the given function or class comes from right where it is used. It saves me from scrolling to the top of the module to get that info.

As for the long module names I just use the as keyword and give them short aliases:

import collections as col
import foomodule as foo
import twisted.internet.protocol as twip

my_dict = col.defaultdict()
twip_fac = twip.Factory()

As an exception I always use the from module import something notation when I deal with the __future__ module. You just can't do it another way when you want all strings to be unicode by default in Python 2, e.g.

from __future__ import unicode_literals
from __future__ import print_function
  • Amen! "import as" is a winning combination :-) – paj28 Mar 4 '15 at 17:40

I use from imports whenever it improves readability. For example, I prefer (semicolons are only to save space here):

from collections import defaultdict
from foomodule import FooBar, FooBaz
from twisted.internet.protocol import Factory
defaultdict(); FooBar(); FooBaz(); Factory()

instead of:

import collections
import foomodule
import twisted.internet.protocol
collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz()

The latter is harder to read (and write) for me because it contains so much redundant information. Also, it's useful to know ahead of time what parts of a module I'm using.

I prefer regular imports if I'm using lots of short names from a module:

import sys
sys.argv; sys.stderr; sys.exit()

Or if a name is so generic that it doesn't make sense outside of its namespace:

import json

from json import loads
loads(foo)  # potentially confusing
  • This is my favorite answer. 'Explicit is better than implicit' sometimes conflicts with readability, simplicity, and DRY. Especially when using a framework like Django. – neuronet Jan 3 at 17:27

Although import sys and from sys import agrv both import the entire sys module, the latter uses name binding so only the argv module is accessible to rest of the code.

For some people this would be the preferred style since it only makes accessible the function you explicitly stated.

It does however introduce potential name conflicts. What if you had another module named argv? Note you can also explicitly import the function and rename with from sys import argv as sys_argv, a convention that meets the explicit import and is less likely to gave name space collisions.

  • 1
    So how is if sys_argv: any better than if sys.argv:? I know what the second statement means, I have no idea what the first form means without backtracking to the bizarre import. – msw Nov 15 '15 at 17:54

I recently asked this question to myself. I timed the different methods.

requests library

def r():
    import requests
    return 'hello'
timeit r() # output: 1000000 loops, best of 3: 1.55 µs per loop

def rg():
    from requests import get
    return 'hello'
timeit rg() # output: 100000 loops, best of 3: 2.53 µs per loop

beautifulsoup library

def bs():
    import bs4
    return 'hello' 
timeit bs() # output: 1000000 loops, best of 3: 1.53 µs per loop

def be():
    from bs4 import BeautifulSoup
    return 'hello'
timeit be() # output: 100000 loops, best of 3: 2.59 µs per loop

json library

def js():
    import json
    return 'hello'
timeit js() # output: 1000000 loops, best of 3: 1.53 µs per loop

def jl():
    from json import loads
    return 'hello'
timeit jl() # output: 100000 loops, best of 3: 2.56 µs per loop

sys library

def s():
    import sys
    return 'hello'
timeit s() # output: 1000000 loops, best of 3: 1.55 µs per loop

def ar():
    from sys import argv
    return 'hello'
timeit ar() # output: 100000 loops, best of 3: 2.87 µs per loop

It seems to me that there is a slight difference in performance.

  • You are adding in an attribute lookup. To compare import module with from module import name correctly, add that name lookup to the import module case. E.g. add the line sys.argv to the ar test, etc. There will still be a difference, because the work done is slightly different, as different bytecode is generated and different codepaths are executed. – Martijn Pieters Jan 8 '15 at 11:44
  • 2
    Note that I directly address that difference in my answer; there will be a difference between using import sys then using sys.argv thousands of time in a loop vs. from sys import argv then using just argv. But you don't. For things you do just once at the global level of your module, you really should optimise for readability, not microscopic differences in timings. – Martijn Pieters Jan 8 '15 at 11:47
  • Ahhhh! And I thought I was on to something! :) I only skimmed your answer. Looks like I jumped the gun on that one. Feels good to be humbled. – tmthyjames Jan 8 '15 at 16:07

Looking at published code fragments, importing entire modules and referring to module.function is pretty much the standard, at least for standard modules. The one exception seems to be datetime

from datetime import datetime, timedelta

so you can say datetime.now() rather than datetime.datetime.now().

If you are concerned about performance, you can always say (for example)

argv = sys.argv

and then do your performance critical code since the module lookup is already done. However although this will work with functions/methods, most IDE's will get confused and won't (for example) display a source link/signature for the function when it's assigned to a variable.

I just want to add that if you do something like

from math import sin

(or any other built-in library like sys or posix), then sin will be included in the documentation for your module (ie when you do >>> help(mymodule) or $ pydoc3 mymodule. To avoid this, import using:

import math
from math import sin as _sin

PS: a built-in library is one that is compiled from C code and included with Python. argparse, os and io are not built-in packages

protected by gnat Jun 3 '16 at 17:35

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.