If I create a package named foo
that imports bar
, why is bar
visible under foo
as foo.bar
when I import foo
in another module? Is there a way to prevent this; to keep bar
hidden so as not to clutter the namespace?

- 5,976
- 7
- 29
- 42
-
Import bar directly into the other module – sshashank124 Jul 01 '14 at 06:58
-
2How would that prevent `foo.bar` from being visible? And in any event, `foo` still requires `bar` so I can't just eliminate the `import`. – Emre Jul 01 '14 at 07:01
-
1[Relevant SO discussion](http://stackoverflow.com/questions/1024049/is-it-pythonic-to-import-inside-functions) – pandita Jul 01 '14 at 07:26
-
1Is there anything that is invisible in python? I think it's the philosophy of the programming language not to hide things.. – Alexander Oh Jul 01 '14 at 07:51
-
@Alex `private`/`protected`?? – rjv Jul 01 '14 at 08:10
-
1@rjv private members in python are private by convention not by implementation. see also: http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private – Alexander Oh Jul 01 '14 at 08:43
3 Answers
Import bar wherever you use it, rather than globally
If bar is being used in a function, import as
def func():
import bar
....
Or even,
if __name__ == '__main__':
import bar
my_main(bar)
Or if you love class
es,
class Fubar():
def __init__(self):
import bar
self.bar = bar

- 6,058
- 5
- 27
- 49
-
Will importing bar every time func is called harm performance? [It seems so.](http://stackoverflow.com/questions/18462935/does-importing-more-slow-down-scripts-python) – Emre Jul 01 '14 at 07:25
-
It will, you can consider setting the bar as instance of a class and use it, if you use classes – rjv Jul 01 '14 at 07:28
-
1@Emre Time it. Here, `python -m timeit 'import sys' 'sys.argv[1]'` needs `1000000 loops, best of 3: 0.965 usec per loop`, while `python -m timeit '' 'import sys; sys.argv[1]'` needs `1000000 loops, best of 3: 0.957 usec per loop`. So it's essentially the same. – glglgl Jul 01 '14 at 07:30
Imports in Python are really just another form of name assignment. There is really no difference between an object that has been imported into foo and one that has been defined in foo - they are both visible internally and externally in exactly the same way. So no, there is no way to prevent this.
I don't really see how this is cluttering the namespace, though. You've still only imported one name, foo, into your other module.

- 588,541
- 66
- 880
- 895
-
If you import a long list of packages, it can crowd out the ones you actually want to expose when you do command completion. It's pollution from the user's perspective. – Emre Jul 01 '14 at 07:22
-
But you're not importing a list, you're just importing foo. The modules imported inside foo shouldn't affect autocompletion, surely. – Daniel Roseman Jul 01 '14 at 07:33
-
I meant to say there are packages besides foo that are similarly imported. Autocomplete does indeed see and suggest bar. – Emre Jul 01 '14 at 07:34
TL;DR: Python Imports create named bindings for pieces of code so they can be referenced and used.
An import is essentially binding a piece of code to a name. So the namespace should always reflect what has been imported. If you hide that you may end up causing unexpected problems for someone else or yourself.
If you are importing the wrong modules, importing modules you don't use, or have a ton of imports because you have 10 classes in one file you should consider fixing the underlying issue(s). Not trying to hide it by messing with how modules are imported.

- 8,556
- 1
- 30
- 34