通过一次导入在python应用程序中访问全局变量

时间:2018-06-28 18:00:18

标签: python global-variables

所以,我想做的是将python解释器用作服务器端python应用程序的CLI。但是,我在加载python模块时遇到了意外的行为。

我有两个python文件和一个缓存文件:

  

Main.py
  Config.py
  Cache.json

因此,发生的情况是,在导入和运行Main时,main()函数将导入Configs,然后调用一个函数以初始化Config。初始化后,Config会根据我正在运行的环境从Cache.json加载一些全局变量。这是.py的简化示例。

#Main.py
import Config

def main():
    """Initialize Python Application"""
    Config.init()


if __name__ == "__main__":
    main()
  

#Config.py
import os
import json

Default_MSSQLPassword = ""
Default_MSSQLUser = ""
Default_OdbccDriver = ""
MDGSQLP01 = ""


def init():
    """docstring"""

    with open("Cache.json", "r") as f:
        dtGlobalConstants = json.load(f)

    Default_MSSQLPassword = dtGlobalConstants["Default_MSSQLPassword"]
    Default_MSSQLUser = dtGlobalConstants["Default_MSSQLUser"]
    Default_OdbccDriver = dtGlobalConstants["Default_OdbccDriver"]
    MDGSQLP01 = dtGlobalConstants["MDGSQLP01"]

现在从理论上讲,如果我在python解释器中调用以下代码:

>>>from Main import main
>>>main()

Config应该由main()导入,并保持不变,并且我应该能够打印从Cache.json加载的Default_OdbccDriver的Cached值。但是我得到了这个:

>>>Config.Default_OdbccDriver
>>>''

因此很明显Main正在导入Config.py,因为否则在调用属性.Default_OdbccDriver时会出现错误。但是,即使Default_OdbccDriver的值被假定为“全局”(根据python对该词的奇异定义),它的值也应该是静态的,并保留在导入缓存中。

任何人都知道发生了什么或如何解决?最后,我希望main()初始化一些值并公开一些使用我的应用程序的方法,但这不是一个好的开始...

2 个答案:

答案 0 :(得分:3)

您应该在global函数中将变量声明为init,否则,您将设置函数的某些局部变量以使全局变量不受影响:

def init():
    """docstring"""
    global Default_MSSQLPassword
    global Default_MSSQLUser
    global Default_OdbccDriver
    global MDGSQLP01

    with open("Cache.json", "r") as f:
        dtGlobalConstants = json.load(f)

    Default_MSSQLPassword = dtGlobalConstants["Default_MSSQLPassword"]
    Default_MSSQLUser = dtGlobalConstants["Default_MSSQLUser"]
    Default_OdbccDriver = dtGlobalConstants["Default_OdbccDriver"]
    MDGSQLP01 = dtGlobalConstants["MDGSQLP01"] 

正如您在评论中所说,在导入会话时,将变量绑定到Main.Config.your_var_name以解决此问题,足以在模块中将它们声明为全局变量:

#Config.py
import os
import json

global Default_MSSQLPassword
global Default_MSSQLUser
global Default_OdbccDriver
global MDGSQLP01

Default_MSSQLPassword = ""
Default_MSSQLUser = ""
Default_OdbccDriver = ""
MDGSQLP01 = ""


def init():
    """docstring"""
    global Default_MSSQLPassword
    global Default_MSSQLUser
    global Default_OdbccDriver
    ...

答案 1 :(得分:0)

似乎您正在使用config,就像它是一类一样,但是没有将其定义为一个类。如果需要配置对象,则可以这样定义它:

#Config.py
import os
import json

class Config:

    def __init__(self):
        """docstring"""

    dtGlobalConstants = {}

    with open("Cache.json", "r") as f:
        dtGlobalConstants = json.load(f)

    Default_MSSQLPassword = dtGlobalConstants.get("Default_MSSQLPassword", "")
    Default_MSSQLUser = dtGlobalConstants.get("Default_MSSQLUser", "")
    Default_OdbccDriver = dtGlobalConstants.get("Default_OdbccDriver", "")
    MDGSQLP01 = dtGlobalConstants.get("MDGSQLP01", "")

现在,当您首次实例化配置对象时,例如config = Config()config对象将具有所有这些变量。

还请注意,如果dict.get()函数在该dict中找不到变量,则会将其设置为“”。

如果您改用类,则可以避免使用全局变量,甚至可以通过编写get_db_object函数来更新配置以从功能上返回数据库对象,这样您就可以使用config.get_db_object()创建您的数据库对象