структура пакета Python и глобальные переменные - PullRequest
0 голосов
/ 31 января 2012

Я создал пакет в Python. В файле init я поместил переменную, которая должна быть доступна во всех модулях этого пакета.

Пример:

# main script    
from _Framework.STB import DB
DB.environment = 'lab'
channel = DB.Channels.ChannelStatic.getChannelByNumber(416)
...

# Channels.py module in the package
from _Framework.DB.__init__ import cursor
from _Framework.DB.__init__ import environment
from time import *
...

Проблема в том, что вечный вызов

from _Framework.DB.__init__ import xy

перезаписывает мои "глобальные" переменные

Как я могу решить?

Спасибо

EDIT:

init.py:

all = [ 'Events', 'Channels', 'Genres', 'Subgenres','EPGSections'] 
try: 
    conn = MySQLdb.connect(host,user,passwd,db) 
    cursor = conn.cursor(MySQLdb.cursors.DictCursor) 
except: 
    cursor = None 
    environment = 'live'

Я импортирую пакет БД и устанавливаю переменную «environment», но, когда модуль Channels импортируется, я думаю, он выполняет новый вызов init.py и повторно выполняет свой код, так что «environment» перезаписывается. Я ищу чистый способ поделиться переменной между модулями одного пакета

Ответы [ 2 ]

2 голосов
/ 31 января 2012

Импорт из модуля __init__ как

from package.__init__ import X

запускает код модуля каждый раз. Вот почему ваша переменная перезаписывается. Это связано с тем, что модуль __init__ добавляется дважды (с разными именами) в sys.modules. Во-первых, как имя вашего пакета, когда он импортирует его, затем как package.__init__ при явном импорте. Поскольку источник загружается дважды, код выполняется дважды.

Однако вам не нужно делать это так, вам нужно только сделать:

from _Framework.DB import cursor
from _Framework.DB import environment

Тогда ваш код будет выполняться только один раз.

0 голосов
/ 31 января 2012

Я все еще не уверен, но правильно ли я понимаю. Вы должны просто использовать редактирование вашего вопроса и опубликовать правильно отформатированный код:

__init__.py:

all = [ 'Events', 'Channels', 'Genres', 'Subgenres','EPGSections']
try:
    conn = MySQLdb.connect(host,user,passwd,db)
    cursor = conn.cursor(MySQLdb.cursors.DictCursor)
except:
    cursor = None
    environment = 'live

Теперь в Channels.py вы хотите изменить _Framework.DB.__init__.cursor и _Framework.DB.__init__.environment, и эти изменения должны быть видны во всей вашей программе?

Если это то, что вы хотите, вы должны знать, что при импорте:

 from _Framework.DB.__init__ import cursor
 from _Framework.DB.__init__ import environment

В результате вы получаете две переменные курсора и среды в пространстве имен вашего модуля Channels.py, и любые сделанные вами изменения будут видны только в этом модуле. Если вы хотите добиться своего результата, попробуйте это:

import _Framework.DB

_Framework.DB.cursor = new_cursor
_Framework.DB.environment = new_environment

Таким образом, вы фактически меняете переменные модуля. Теперь в остальной части вашей программы, когда вы хотите, чтобы изменения вступили в силу, вы можете:

  1. Принимает переменные так же, как вы их изменили:

    import _Framework.DB

    _Framework.DB.cursor        #changes made in other module will have effect
    _Framework.DB.environment   #changes made in other module will have effect
    
  2. импортируйте, как вы, но убедитесь, что необходимые изменения сделаны ДО того, как вы выполните какой-либо импорт.

    В качестве отрицательного примера для второго случая:

    #module Vars
    a = 1
    
    --------------------------
    
    #module Do_change
    import Vars
    Vars.a = 2
    
    --------------------------
    
    #module A
    from Vars import a
    
    
    --------------------------
    
    #module B
    from Vars import a
    
    --------------------------
    
    #some random module
    import A
    import Do_change
    import B
    

Теперь, если вы находитесь в таком порядке импорта, когда вы импортируете A, он создаст переменную a в пространстве имен A со значением Vars.a. Do_change отредактирует переменную соответственно, но A не будет знать об этом. Однако, кто будет импортирован после, увидит правильное значение Vars.a = 2.

Вот почему я действительно рекомендую первый вариант, так как, на мой взгляд, это правильный подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...