5

Overview

Suppose I'm building a class for general usage: I might need to import it wherever, use it in a couple other files, etc. Should the import go before the class, as:

import foo

class Bar():

    def __init__(self):
        foo.spam()

Or inside the __init__ method, as:

class Bar():

    def __init__(self):

        import foo

        foo.spam()

My Analysis

Outside

+ Brings the foo into the global namespace for use throughout Bar

- Importing Bar also requires you to manually import foo (@MartijnPieters et al.)

Inside

+ Avoids loading foo before you actually need to

+ foo loads when Bar is instantiated imported (and used) (@BrenBarn)

- foo is unavailable elsewhere

user126350
  • 505
  • 5
  • 11
  • 2
    *Importing Bar also requires you to manually import foo*: no, it doesn't. `Bar.__init__` looks up globals *in its own module*. – Martijn Pieters Sep 03 '14 at 17:57

2 Answers2

5

Usually all imports go at the top of the module. That makes it easy to see the dependencies of a module at a glance, either by visual inspection or in a code checker like pyflakes. Your assumption that "importing Bar also requires you to manually import foo" is false.

The only times you would imports inside functions or methods are when the imports are very resource-intenstive (e.g., slow) or unreliable (e.g., optional dependencies that may not be installed, platform-specific modules or modules that tend to break), and client code is not expected to always call the functions in question.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 2
    We do imports within a function when delivering multi-platform unittests for those tests that are no compatible on all platforms (for example, import winreg only on windows) – user590028 Sep 03 '14 at 18:02
3

There are some related questions here and here, among others. The bottom line is that it's usually best to put all the imports at the top unless you have a good and specific reason not to do so.

As for your analysis:

Importing Bar also requires you to manually import foo

No. Importing Bar will automatically import foo, and Bar will be able to use foo regardless of what any other code does. Imports create a reference to the imported module only inside the module doing the import (that is, they don't make the imported name "globally available" across all modules).

  • foo loads when Bar is imported (and used)

Note that "imported" and "used" aren't the same thing. In your example foo will be imported when Bar is instantiated (with Bar()), because it is inside the __init__ method. It won't be loaded when Bar is imported.

  • Avoids loading foo before you actually need to

This is true, but in practice it usually gains you little. It only makes sense to worry about this if there is a reasonably high chance that someone using your module will not ever need to use the part that imports foo (i.e., Bar). Even then, it only makes sense if importing foo is slow, resource-intensive, or sometimes may not work (e.g., if foo is a library that may not be available on all platforms). For most modules, you gain little by deferring the import.

Which brings up one big reason not to do the local import: it makes it harder to know what the dependencies of a module are. It's handy to be able to look at the top of a module and see everything it needs to import. If crucial imports are hidden deep inside code, it's more difficult to understand what other modules need to be available.

Community
  • 1
  • 1
BrenBarn
  • 242,874
  • 37
  • 412
  • 384