Python: как получить доступ к переменной, объявленной в родительском модуле
Использование структуры из документов Python:
sound/
__init__.py
effects/
__init__.py
echo.py
surround.py
reverse.py
Скажем, я хочу import sound.effects
и получить список доступных эффектов. Я мог бы сделать это, объявив переменную уровня модуля в sound.effects
, а затем добавив к ней, когда будет импортирован каждый .py файл. Таким образом, звук/эффекты/__ init__.py может выглядеть так:
effectList = []
import echo
import surround # Could write code to import *.py instead
...
Из моего основного кода я могу теперь получить доступ к sound.effects.effectList
, чтобы получить список эффектов, но как мне получить доступ к effectList
изнутри echo.py, чтобы сделать фактическое добавление? Я застреваю, пытаясь получить доступ к переменной:
# None of these work :-(
# from . import self
# from .. import effects
# import sound.effects
sound.effect.effectList.append({'name': 'echo'})
Ответы
Ответ 1
То, что обычно делают люди в этой ситуации, это создать файл common.py в модуле.
sound/
__init__.py
effect/
__init__.py
common.py
echo.py
surround.py
reverse.py
Затем вы переместите код с __init__.py
на common.py
:
effectList = []
import echo
import surround # Could write code to import *.py instead
...
Внутри __init__.py
у вас есть следующее:
from common import *
Итак, теперь в echo.py
у вас будет следующее:
import common
common.effectList.append({'name': 'echo'})
Любой импортирующий звук будет использовать его так:
import sound.effect
for effect_name,effect in sound.effect.effectlist.items():
#....
Я только начал использовать это самостоятельно, но я считаю, что это обычная практика в сообществе python.
Ответ 2
Я думаю, что вы должны оставить "сделать доступным" в __init__.py
внутри пакета effects
, а не все модули автоматически заполнять effectList
. Несколько причин, о которых я могу думать.
- Вы не можете импортировать какие-либо эффекты, кроме как через пакет, если вам удалось каким-то образом получить эту работу (кроме модуля
effectList
в модуле импорта).
- Вам нужно вручную добавить приложение в каждом произнесенном вами эффекте. Было бы лучше, если бы вы только что внедрили
import *.py
как вещь в __init__.py
, которая загружала все в текущую директорию и делала ее доступной.
Что-то вроде этого в вашем __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)