Python import dependencies
Question: I am dynamically creating some python code that I want to run inside a
wrapper. Here is an overly simplified example.

[wrapper.py]

    
    
    import cv2
    img = cv2.imread('pic.png',0)
    
    __import__("fragment")
    
    cv2.imshow('pic',img)
    

[fragment.py]

    
    
    img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    

I want the wrapper to set up any imports and variables, then import the
fragment which will do stuff (i.e. make the image grayscale) and then do some
standardized stuff afterwards (i.e. display image).

The fragments will be changing (genetic algorithm) so I would prefer to keep
them separate from the setup which will be constant and will just get make
manipulating the fragments more complicated.

When I run the program I get dependency errors on the fragment because cv2 and
img are not defined (scope errors). Is there a way to achieve this either with
a correction to the method I have used above or with another method?

I expect I might be able to also create the composite of the files in ram and
then exec it or write over the fragment with a version of itself that contains
all of the needed wrapping, but I wanted to see if there was something cleaner
first.

Sincerely, Paul.


Answer: > The fragments will be changing (genetic algorithm) so I would prefer to keep
> them separate from the setup which will be constant and will just get make
> manipulating the fragments more complicated.

Whatever the complexity of the genetic algorithms you implemented in
`fragment.py` is, I do not see how importing `cv2` (and eventually more
modules) will impact it in a way or an other.

However, I agree with the first part of your statement in that you want to
respect the principle of _[separation of
concerns](https://en.wikipedia.org/wiki/Separation_of_concerns)_ and make your
code cleaner.

The solution I see for your problem is to set a configuration file `config.py`
in which you set all your imports. But importing `config.py` into other files
is useless unless you succeed to make modules such as `cv2` available
elsewhere once for all. You can achieve that by _[dynamically importing
them](http://www.diveintopython.net/functional_programming/dynamic_import.html)_
within `config.py` file:

    
    
    cv2=__import__('cv2')
    

in your main program, `fragment.py` file or whatever module, you can make use
of `cv2` by simply running this:

    
    
    import config
    config.cv2.imread('pic.png')
    

`import config` ↔ you do not need anymore to run: `import cv2`. This is
because this trick renders `cv2` as a global variable available across
multiple modules.

The same idea is valid for your other variables such as `img` that you need to
declare in your `config.py` file too.

Given these facts, here is my solution for your problem. Note that I am not
using classes and functions: I prefer to address your problem
straightforwardly and keep things too simple and clear instead.

**Organization of the code:**

The `config.py` file corresponds to your `wrapper.py`:

    
    
    solution/
    ├── application.py
    ├── cfg
    │   ├── config.py
    │   └── __init__.pyc
    ├── gallery
    │   └── pic.png
    └── genalgos
        ├── fragment.py
        └── __init__.py
    

**config.py:**

    
    
    # This will make cv2 global and thus you won't need to import it in ./genalgos/fragment.py
    # You can use the same idea for all your other imports
    cv2=__import__('cv2')
    imgc=cv2.imread('./gallery/pic.png') # imgc is global
    

**fragment.py:**

    
    
    # The only import you can not avoid is this one
    import cfg.config
    
    # imgs is global
    # By importing cfg.config you do not need to import cv2 here
    imgf=cfg.config.cv2.cvtColor(cfg.config.imgc,cfg.config.cv2.COLOR_BGR2GRAY) 
    

**application.py:**

    
    
    import cfg.config
    import genalgos.fragment
    if __name__=="__main__":
    
       """
        Display the image 'imgc' as it is in 'cfg/config' file
       """
       cfg.config.cv2.imshow('Pic in BGR',cfg.config.imgc)
       cfg.config.cv2.waitKey(0)
       cfg.config.cv2.destroyAllWindows()
    
       """
        Display the grascaled image 'imgf' as it is in 'genalgos/fragment' file which
        itself is obtained after transforming imgc of 'cfg/config' file.
       """
       cfg.config.cv2.imshow('PIC Grayscaled',genalgos.fragment.imgf)
       cfg.config.cv2.waitKey(0) # Press any key to exit
       cfg.config.cv2.destroyAllWindows() # Unpaint windows and leave
    

