1

Let's say I have a file where I'm importing some packages:

# myfile.py
import os
import re
import pathlib

def func(x, y):
    print(x, y)

If I go into another file and enter

from myfile import *

Not only does it import func, but it also imports os, re, and pathlib,

but I DO NOT want those modules to be imported when I do import *.

Why is it importing the other packages I'm importing and how do you avoid this?

Zack Plauché
  • 3,307
  • 4
  • 18
  • 34
  • 9
    Congrats, you've found one of the many reasons not to use `import *`. Stop using it! – user2357112 Jan 11 '21 at 18:09
  • Does this answer your question? [Can someone explain \_\_all\_\_ in Python?](https://stackoverflow.com/questions/44834/can-someone-explain-all-in-python) – mkrieger1 Jan 11 '21 at 18:09
  • `Why is it importing the other packages I'm importing and how do you avoid this?` If everything(hence `import *`) on your package works without those libraries, why are you importing them? – Mikael Jan 11 '21 at 18:09
  • If those aren't necessary to import, then why are they in the module you're importing? If you're wanting to import things from your module that rely on those, why would you want to not import the modules that those rely on? – Random Davis Jan 11 '21 at 18:11

4 Answers4

5

The reason

Because import imports every name in the namespace. If something has a name inside the module, then it's valid to be exported.

How to avoid

First of all, you should almost never be using import *. It's almost always clearer code to either import the specific methods/variables you're trying to use (from module import func), or to import the whole module and access methods/variables via dot notation (import module; ...; module.func()).

That said, if you must use import * from module, there are a few ways to prevent certain names from being exported from module:

  1. Names starting with _ will not be imported by import * from .... They can still be imported directly (i.e. from module import _name), but not automatically. This means you can rename your imports so that they don't get exported, e.g. import os as _os. However, this also means that your entire code in that module has to refer to the _os instead of os, so you may have to modify lots of code.

  2. If a module contains the name __all__: List[str], then import * will export only the names contained in that list. In your example, add the line __all__ = ['func'] to your myfile.py, and then import * will only import func. See also this answer.

Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
  • This is actually what I was looking for. If I just import myfile I didn't want to import the other things as well (like re, os, or pathlib in this case) – Zack Plauché Jan 11 '21 at 18:16
1
from myfile import func

Here is the fix :)

When you import *, you import everything from. Which includes what yu imported in the file your source.

Synthase
  • 5,849
  • 2
  • 12
  • 34
0

It has actually been discussed on Medium, but for simplification, I will answer it myself.

from <module/package> import * is a way to import all the names we can get in that specific module/package. Usually, everyone doesn't actually use import * for this reason, and rather sticked with import <module>.

0

Python's import essentially just runs the file you point it to import (it's not quite that but close enough). So if you import a module it will also import all the things the module imports. If you want to import only specific functions within the module, try:

from myfile import func

...which would import only myfile.func() instead of the other things as well.