61

I created a module named util that provides classes and functions I often use in Python. Some of them need imported features. What are the pros and the cons of importing needed things inside class/function definition? Is it better than import at the beginning of a module file? Is it a good idea?

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
Maciej Ziarko
  • 11,494
  • 13
  • 48
  • 69
  • 1
    possible duplicate of [Good or bad practice in Python: import in the middle of a file](http://stackoverflow.com/questions/1188640/good-or-bad-practice-in-python-import-in-the-middle-of-a-file) – Sven Marnach Mar 10 '11 at 16:14
  • Possible duplicate of [Is it pythonic to import inside functions?](https://stackoverflow.com/questions/1024049/is-it-pythonic-to-import-inside-functions) – John Y Sep 20 '19 at 16:16

6 Answers6

59

It's the most common style to put every import at the top of the file. PEP 8 recommends it, which is a good reason to do it to start with. But that's not a whim, it has advantages (although not critical enough to make everything else a crime). It allows finding all imports at a glance, as opposed to looking through the whole file. It also ensures everything is imported before any other code (which may depend on some imports) is executed. NameErrors are usually easy to resolve, but they can be annoying.

There's no (significant) namespace pollution to be avoided by keeping the module in a smaller scope, since all you add is the actual module (no, import * doesn't count and probably shouldn't be used anyway). Inside functions, you'd import again on every call (not really harmful since everything is imported once, but uncalled for).

  • I think the best argument for this is: If you import the file, you want to check at import if you have all the right packages, not at the point you will use a certain function. Of course it could be that you don't need all the packages (I guess this is the downside) – Laurens Meeus Feb 01 '18 at 14:15
18

PEP8, the Python style guide, states that:

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

Of course this is no hard and fast rule, and imports can go anywhere you want them to. But putting them at the top is the best way to go about it. You can of course import within functions or a class.

But note you cannot do this:

def foo():
    from os import *

Because:

SyntaxWarning: import * only allowed at module level
AJM
  • 1,317
  • 2
  • 15
  • 30
user225312
  • 126,773
  • 69
  • 172
  • 181
  • When I put import statements at the beginning of the module, and then use this module in a different file and call `dir(util)` in it, I see not only names of functions/classes I defined inside `util.py` but also `imports` that are made there. Is it good? – Maciej Ziarko Mar 10 '11 at 16:26
  • Yes, because `import` executes all of the statements in the loaded source file. So let's suppose there is a module `X` which imports `Y`. Now when we import `X` in another module, `Y` is also imported. – user225312 Mar 10 '11 at 16:30
  • I just thought it violates encapsulation as anyone has some access to the implementation (gets information about modules I used). – Maciej Ziarko Mar 10 '11 at 16:37
  • 2
    This answer isn't very informative--it doesn't say anything about *why*, and that's what matters. – Glenn Maynard Mar 10 '11 at 17:15
  • 1
    So say I've written a module with 3 classes, but only one of them needs `os.path.exists()`. So according to PEP8 my module has to do `from os import path` even though nothing else aside one line uses it in the entire module ? – Sergiy Kolodyazhnyy Feb 12 '19 at 22:02
4

Like flying sheep's answer, I agree that the others are right, but I put imports in other places like in __init__() routines and function calls when I am DEVELOPING code. After my class or function has been tested and proven to work with the import inside of it, I normally give it its own module with the import following PEP8 guidelines. I do this because sometimes I forget to delete imports after refactoring code or removing old code with bad ideas. By keeping the imports inside the class or function under development, I am specifying its dependencies should I want to copy it elsewhere or promote it to its own module...

Will Charlton
  • 862
  • 10
  • 11
4

Only move imports into a local scope, such as inside a function definition, if it’s necessary to solve a problem such as avoiding a circular import or are trying to reduce the initialization time of a module. This technique is especially helpful if many of the imports are unnecessary depending on how the program executes. You may also want to move imports into a function if the modules are only ever used in that function. Note that loading a module the first time may be expensive because of the one time initialization of the module, but loading a module multiple times is virtually free, costing only a couple of dictionary lookups. Even if the module name has gone out of scope, the module is probably available in sys.modules.

https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module

N.Y
  • 41
  • 1
2

I believe that it's best practice (according to some PEP's) that you keep import statements at the beginning of a module. You can add import statements to an __init__.py file, which will import those module to all modules inside the package.

So...it's certainly something you can do the way you're doing it, but it's discouraged and actually unnecessary.

Ramy
  • 20,541
  • 41
  • 103
  • 153
2

While the other answers are mostly right, there is a reason why python allows this.

It is not smart to import redundant stuff which isn’t needed. So, if you want to e.g. parse XML into an element tree, but don’t want to use the slow builtin XML parser if lxml is available, you would need to check this the moment you need to invoke the parser.

And instead of memorizing the availability of lxml at the beginning, I would prefer to try importing and using lxml, except it’s not there, in which case I’d fallback to the builtin xml module.

flying sheep
  • 8,475
  • 5
  • 56
  • 73