Malvineous
Malvineous

Reputation: 27300

Python: How to access variable declared in parent module

Using the structure from the Python docs:

sound/
  __init__.py
  effects/
          __init__.py
          echo.py
          surround.py
          reverse.py

Say I want to import sound.effects and get a list of available effects. I could do this by declaring a module-level variable in sound.effects and then appending to it when each .py file is imported. So sound/effects/__init__.py might look like this:

effectList = []
import echo
import surround   # Could write code to import *.py instead
...

From my main code I can now access sound.effects.effectList to get a list of effects, but how do I access effectList from within echo.py to do the actual append? I'm stuck trying to get access to the variable:

# None of these work :-(
# from . import self
# from .. import effects
# import sound.effects

sound.effect.effectList.append({'name': 'echo'})

Upvotes: 13

Views: 13849

Answers (2)

Eric Palakovich Carr
Eric Palakovich Carr

Reputation: 23308

What people commonly do in this situation is create a common.py file in the module.

sound/
  __init__.py
  effect/
          __init__.py
          common.py
          echo.py
          surround.py
          reverse.py

Then you move the code from __init__.py to common.py:

effectList = []
import echo
import surround   # Could write code to import *.py instead
...

Inside __init__.py you have this:

from common import *

So now in echo.py you'd have this:

import common
common.effectList.append({'name': 'echo'})

Anything importing sound would use it like this

import sound.effect

for effect_name,effect in sound.effect.effectlist.items():
    #....

I've only just started using this myself, but I believe it's common practice in the python community.

Upvotes: 10

Noufal Ibrahim
Noufal Ibrahim

Reputation: 72755

I think you should leave the "making available" to the __init__.py inside the effects package rather than have all the modules auto populate the effectList. A couple of reasons I can think of.

  1. You can't import any of the effects except via the package if you did manage to get this work somehow (they'd except an effectList in the importing module).
  2. You have to manually do the append in every effect you write. It would be better if you just implemented an import *.py like thing in your __init__.py that loaded everything up in the current directory and made it available.

Something like this in your __init__.py.

import os, glob

effectslist = []

for i in glob.glob("*.py"):
    if i == "__init__.py":
        next
    print "Attempting to import %s"%i
    try:
        mod = __import__(os.path.splitext(i)[0])
        effectslist.append(mod)
    except ImportError,m:
        print "Error while importing %s - %s"%(i,m)

Upvotes: 3

Related Questions