11

My package looks like this:

enter image description here

These helpers, since they are all dealing with scipy, all have common imports:

from matplotlib import pyplot as plt
import numpy as np

I'm wondering if it is possible to extract them out, and put it somewhere else, so I can reduce the duplicate code within each module?

martineau
  • 119,623
  • 25
  • 170
  • 301
ZK Zhao
  • 19,885
  • 47
  • 132
  • 206
  • 4
    Not really, each module needs to explicitly import the stuff it needs. However, this doesn't impact efficiency since the interpreter will not re-load modules that have already been loaded (unless explicitly told to do so via the `reload` function). – PM 2Ring Jan 30 '16 at 13:43
  • There are way to do it with `importlib`, but you would spend more time getting it right than you would save in typing/maintenance. – rbp Jan 30 '16 at 13:44
  • @rbp I just thought maintaining duplicate code is not really a good thing. – ZK Zhao Jan 30 '16 at 13:45
  • 2
    Sure, [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) is a great principle, but it doesn't really apply to "header" stuff, like imports. – PM 2Ring Jan 30 '16 at 13:47
  • Don't hate me but it's possible to do: `import builtins; import os; builtins.os = os`. *Runs away banging the door*. – Bakuriu Jan 30 '16 at 13:50
  • @PM2Ring I disagree. It is essentially standardising a set of dependencies, which is a good thing. – andyhasit Jan 30 '16 at 13:51
  • Sure, it's _possible_, just not necessarily a good idea. :) – PM 2Ring Jan 30 '16 at 13:52
  • 2
    @AndyHasIt: Fair point. But replacing 2 simple `import` lines with approximately the same amount of code to pull in the imported stuff with some fancy trick doesn't really give much benefit, and it hides those dependencies. I prefer modules to explicitly state their dependencies; YMMV. – PM 2Ring Jan 30 '16 at 13:55
  • @Bakuriu: Whoa! That's evil. :) – PM 2Ring Jan 30 '16 at 13:57
  • 1
    @PM2Ring for two or 3 lines I agree. However I do see science modules with several lines of imports, not all from stb lib, in which case there may be a valid case for tidying it. Although several lines of import is probably a sign of code smell. I've edited my answer to show a balance between explicit and concise, though there are cons to that approach too. – andyhasit Jan 30 '16 at 14:01
  • @rbp just looked at `importlib`, I'm on python 2.7, it seems not well supported. – ZK Zhao Jan 30 '16 at 14:04
  • I use it all the time. works fine. – rbp Jan 30 '16 at 14:06
  • I'm with PM 2Ring on this. Keep it as it is, trying to 'standardize' things like imports is overkill imho. – Dimitris Fasarakis Hilliard Jan 30 '16 at 14:10
  • 1
    @PM2Ring point 2 of the [Zen of Python](https://www.python.org/dev/peps/pep-0020/): *Explicit is better than implicit.* – Mark Ransom Jan 03 '22 at 20:42

2 Answers2

12

You can create a file called my_imports.py which does all your imports and makes them available as * via the __all__ variable (note that the module names are declared as strings):

File my_imports.py:

import os, shutil
__all__ = ['os', 'shutil']

File your_other_file.py:

from my_imports import *
print(os.curdir)

Although you might want to be explicit in your other files:

File your_other_file.py:

from my_imports import os # or whichever you actually need.
print(os.curdir)

Still, this saves you having to specify the various sources each time — and can be done with a one-liner.

andyhasit
  • 14,137
  • 7
  • 49
  • 51
0

Alright, here is my tweak,

enter image description here

Create a gemfile under the package dir, like this

import numpy as np
from matplotlib import pyplot as plt
import matplotlib as mpl

Then, for other files, like app_helper.py

from .gemfile import *

This comes from here Can I use __init__.py to define global variables?

Community
  • 1
  • 1
ZK Zhao
  • 19,885
  • 47
  • 132
  • 206