Мое дело было несколько иным - хотелось динамически импортировать имена констант.py в каждом модуле gameX.__init__.py
(см. Ниже), вызывая их статический импорт, навсегда оставит их в sys.modules (см. Этот excerpt от Beazley, которого я выбрал от this related question).
Вот моя структура папок:
game/
__init__.py
game1/
__init__.py
constants.py
...
game2/
__init__.py
constants.py
...
Каждый gameX.__init__.py
экспортирует метод Init() - так что я изначально имел from .constants import *
во всех тех gameX.__init__.py
, которые я пытался двигаться внутри инициализации() метод.
Моя первая попытка в строках:
@@ -275,2 +274,6 @@ def init():
# called instead of 'reload'
+ yak = {}
+ yak.update(locals())
+ from .constants import * # fails here
+ yak = {x: y for x,y in locals() if x not in yak}
+ globals().update(yak)
brec.ModReader.recHeader = RecordHeader
Не удалось с довольно загадочным:
SyntaxError: import * is not allowed in function 'init' because it contains a nested function with free variables
Я могу заверить вас, нет вложенные функции там.Во всяком случае я взломал и полоснул и в конечном итоге с:
def init():
# ...
from .. import dynamic_import_hack
dynamic_import_hack(__name__)
Где в game.__init__.py
:
def dynamic_import_hack(package_name):
print __name__ # game.init
print package_name # game.gameX.init
import importlib
constants = importlib.import_module('.constants', package=package_name)
import sys
for k in dir(constants):
if k.startswith('_'): continue
setattr(sys.modules[package_name], k, getattr(constants, k))
(для SetAttr см How can I add attributes to a module at run time? время для GetAttr How can I import a python module function dynamically? - Я предпочитаю использовать те, чем прямой доступ к __dict__
)
Это работает, и это более общий, чем подход в принятом ответе, потому что он позволяет вам взломать в одном месте и использовать его из любого модуля. Тем не менее, я не уверен, что это лучший способ его реализовать - собирался задать вопрос, но, поскольку это будет дубликат этого, я отправляю его как ответ и надеюсь получить некоторую обратную связь. Мои вопросы будут следующими:
- Почему этот «SyntaxError: import * не разрешен в функции« init », пока нет вложенных функций?
- режа имеет много предупреждений в its doc - в частности он пытается произвести наиболее релевантную, а не полную, информацию - это полного меня беспокоит немного
- нет ли встроенного способа сделать
import *
? даже в python 3?
Можете ли вы не просто сделать это с 'eval'? –