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.