1

I have a small application that I would like to split into modules so that my code is better structured and readable. The drawback to this has been that for every module that I import using:

import module

I then have to use module.object for any object that I want to access from that module.

In this case I don't want to pollute the global namespace, I want to fill it with the proper module names so that I don't have to use

from module import *

in order to call an object without the module prepend.

Is there a means to do this that isn't consider to be poor use of from import or import?

Anthony O
  • 622
  • 7
  • 26
  • 4
    What's poor use is what `from module import *` does. If you could do the same thing using different syntax, it would still be poor use, no matter how you do it. The fact that you have to either prefix your function by its module or import the functions explicitly _is_ good design and what you should do. – Vincent Savard Jan 13 '17 at 19:46
  • 1
    So, you want to make your code "better structured," but you want to refer to symbols directly without module names??? – DYZ Jan 13 '17 at 19:47
  • I agree, `from module import *` is a shortcut in itself and symbols should be prefaced by their module. – Mat Jones Jan 13 '17 at 19:50
  • 1
    "*I don't want to pollute the namespace, I want to fill it*" - We're all having trouble understanding the distinction. Are you saying you want to import *some* of the modules symbols, but not *all* of them? – Robᵩ Jan 13 '17 at 19:56
  • thanks Vincent, I'll just accept that and prefix – Anthony O Jan 13 '17 at 20:01

3 Answers3

5

Two reasonable options are to import with a shorter name to prepend. E.g.

import module as m
m.foo()

Or explicitly import names that you plan to use:

from module import (foo,bar)
foo()
happydave
  • 7,127
  • 1
  • 26
  • 25
2

You should avoid using an asterisk in your imports always. So to answer your question, I would say no, there isn't a better way than just:

import module

module.method()

OR

import really_long_module_name as mm

mm.method()

Take a look here at the pep8 guide "Imports" section: https://www.python.org/dev/peps/pep-0008/#imports

Wildcard imports ( from import * ) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools. There is one defensible use case for a wildcard import, which is to republish an internal interface as part of a public API (for example, overwriting a pure Python implementation of an interface with the definitions from an optional accelerator module and exactly which definitions will be overwritten isn't known in advance).

Specific is safer than globbing and I try to only import what I need if I can help it. When I'm learning a new module I'll import the whole thing and then once it's in a good state I go back and refactor by specifically importing the methods I need:

from module import method

method()
lmr0125
  • 21
  • 4
0

I would have to say that you should use the module's name. It's a better way of usage, and makes your code free of namespace confusions and also very understandable.

To make your code more beautiful, you could use the as import:

import random as r 
# OR
from random import randint as rint

One solution that I think is not very beautiful, but works, that comes to mind, in case you don't want to pollute the global namespace, you can try to use the import statements, for example, inside functions.

For example:

>>> def a():
...     from random import randint
...     x = randint(0,2)
...     print x
...
>>> a()
1
>>> randint(0,2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'randint' is not defined

This way, the local namespace of the specific function is filled with the values from the module but the global one is clean.

Ofer Arial
  • 1,129
  • 1
  • 10
  • 25
  • Importing a module _in_ a function is such a bad idea http://stackoverflow.com/questions/128478/should-python-import-statements-always-be-at-the-top-of-a-module – DYZ Jan 13 '17 at 20:17
  • I agree it's not the best way to go, but it's not that bad, look here: http://stackoverflow.com/questions/477096/python-import-coding-style/4789963#4789963 – Ofer Arial Jan 13 '17 at 21:00