Question

Consider the following code:

a.py

import os

def print_rand():
    print os.urandom()

And another module:

b.py

from a import *

In this code, I end up with an os variable getting imported from a. I could prevent this with a small change:

a.py

import os as _os

def print_rand():
    print _os.urandom()

Since from a import * does not pick up on members beginning with an underscore, b wouldn't import the os module from a.

I've thought about doing this in some of my code. I never use import *, but logically, it makes some sense anyway. (Not to mention I don't work alone on my code.) os is a member that a uses internally; it's not there to be exposed to the outside world. (Yes, I'm aware that it can be accessed anyway, but I just mean in the sense that the underscore conventionally means "private".)

Is this something I should do? Would it be considered "Pythonic", or is it something I should particularly avoid doing? Does it even matter? (Should I have asked on StackOverflow? It seems too conceptual for there to me.)

Was it helpful?

Solution

I've seen this done, although not often. I wouldn't do this myself, for several reasons:

  • In case of a module, it is not the module itself that is internal, it's the fact of its usage that is internal. The module can be accessed quite legitimately by importing it explicitly, especially the one from the standard library. So the leading underscore will only confuse someone who reads your code.
  • If a user of your package relies on something that is not explicitly mentioned in the documentation (and you probably won't advertise os module as a part of your module's public API), it is not really your problem. Usual assumption in this case is that if you want to use something from the standard library, you import it yourself.
  • PEP8 recommends using __all__ for modules that are imported with import *, which eliminates the problem.
  • The usage of import * is often frowned upon anyway. For example, pylint complains about it.

That said, these are still not 100% compelling reasons, and there may be cases where obscuring the imported module's name in such a way is justified.

Licensed under: CC-BY-SA with attribution
scroll top