2012-01-31 2 views
0

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

Пример:

# 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 * 
... 

Проблема заключается в том, что everdy вызов

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' 

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

+0

Я не совсем понимаю проблему с вами. Можете ли вы опубликовать код __init__.py и еще один код из модуля, в котором импорт «перезаписывает ваши« глобальные »переменные», указывая, что именно перезаписано и кем? – Bogdan

+0

######################### __init__.py __all__ = ['События', 'Каналы', 'Жанры', 'Поджанры', ' EPGSections'] попробовать: соппы = MySQLdb.connect (хост, пользователь, ПАРОЛЬ, дБ) курсора = conn.cursor (MySQLdb.cursors.DictCursor) кроме: курсора = None среды = 'живого' В my_script.py Я импортирую пакет DB, и я установил переменную «среда», но когда импортируется модуль Channels, я думаю, что он вызывает новый вызов __init__.py и повторно выполняет его код, поэтому «среда» перезаписывается , Я ищу чистый способ обмена переменной между модулями одного и того же пакета –

+0

Вы знаете, что можете правильно отредактировать вопрос? –

ответ

0

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

__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 имен и любые изменения do будет отображаться только в этом модуле. Если вы хотите достичь своего результата, попробуйте это:

import _Framework.DB 

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

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

  1. Acces с varibles таким же образом вы изменили их:

    импорт _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 
    

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

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

+0

спасибо человеку за ответ, извините за мой плохой отформатированный ответ, но stackoverflow не позволяет мне ответить на вопрос, прежде чем 8 часов прошло после его публикации. В любом случае я решил, создав еще один модуль Setup и переместив весь код из __init__ внутри него. Он работает сейчас. Я попытаюсь реализовать ваше решение и se, если оно будет работать лучше. Еще раз спасибо! –

2

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

from package.__init__ import X 

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

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

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

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

+0

+1 Действительно, импорт из пакета '__init__' является плохой практикой программирования на питоне. – martineau