python包结构和全局变量

时间:2012-01-31 11:34:32

标签: python module package structure

我在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

覆盖我的“全局”变量

我该如何解决?

由于

编辑:

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模块时,我想,它会对init.py进行新的调用并重新执行其代码,以便覆盖“环境”。我正在寻找一种干净的方式来共享同一个包的模块之间的变量

2 个答案:

答案 0 :(得分:2)

从模块__init__导入,如

from package.__init__ import X

每次都运行模块代码。这就是你的变量被覆盖的原因。这是因为__init__模块在​​sys.modules中被添加两次(具有不同的名称)。首先,在导入时将其作为包的名称,然后在显式导入时将其作为package.__init__。由于源加载了两次,代码执行两次。

但是你不需要像这样做,你只需要这样做:

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

然后你的代码只运行一次。

答案 1 :(得分: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模块命名空间中获得两个变量游标和环境时,您所做的任何更改只会在该模块中可见。如果你想达到你的结果,试试这个:

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
    
  3. 现在,如果您在导入A时处于此导入顺序,它将在A的命名空间中创建一个变量a,其值为Vars.a. Do_change将相应地编辑变量,但A将不知道这一点。 B但是之后导入的人会看到正确的Vars.a = 2。

    这就是我真正推荐第一个选项的原因,因为我认为这是正确的做法。